diff mbox series

cython: swap prefix-mapping patch for an upstream commit

Message ID 20241119161007.2700429-1-ross.burton@arm.com
State New
Headers show
Series cython: swap prefix-mapping patch for an upstream commit | expand

Commit Message

Ross Burton Nov. 19, 2024, 4:10 p.m. UTC
Upstream has solved the absolute path problem differently by taking
paths relative to the top of the module.  This appears to solve the
problem, at least I've not found any cases where it breaks.

Drop my patch, and backport the relevant commit from upstream.

Signed-off-by: Ross Burton <ross.burton@arm.com>
---
 meta/classes-recipe/cython.bbclass            |   3 -
 ...lative-paths-in-generated-C-code.-GH.patch |  73 +++++++++
 .../python3-cython/0001-WIP-prefix-map.patch  | 148 ------------------
 .../python/python3-cython_3.0.11.bb           |   2 +-
 4 files changed, 74 insertions(+), 152 deletions(-)
 create mode 100644 meta/recipes-devtools/python/python3-cython/0001-Output-import-relative-paths-in-generated-C-code.-GH.patch
 delete mode 100644 meta/recipes-devtools/python/python3-cython/0001-WIP-prefix-map.patch
diff mbox series

Patch

diff --git a/meta/classes-recipe/cython.bbclass b/meta/classes-recipe/cython.bbclass
index 53b84f5f5eb..dd9fc732bcb 100644
--- a/meta/classes-recipe/cython.bbclass
+++ b/meta/classes-recipe/cython.bbclass
@@ -1,8 +1,5 @@ 
 DEPENDS:append = " python3-cython-native"
 
-# Remap the build paths that appear in generated .c code
-export CYTHON_PREFIX_MAP = "${S}=${TARGET_DBGSRC_DIR} ${B}=${TARGET_DBGSRC_DIR}"
-
 do_compile[postfuncs] = "strip_cython_metadata"
 strip_cython_metadata() {
     # Remove the Cython Metadata headers that we don't need after the build, and
diff --git a/meta/recipes-devtools/python/python3-cython/0001-Output-import-relative-paths-in-generated-C-code.-GH.patch b/meta/recipes-devtools/python/python3-cython/0001-Output-import-relative-paths-in-generated-C-code.-GH.patch
new file mode 100644
index 00000000000..bbafc294163
--- /dev/null
+++ b/meta/recipes-devtools/python/python3-cython/0001-Output-import-relative-paths-in-generated-C-code.-GH.patch
@@ -0,0 +1,73 @@ 
+From 9b5f3b09f76899eba510c2d8f3ed2b0f752a4d1b Mon Sep 17 00:00:00 2001
+From: Oscar Benjamin <oscar.j.benjamin@gmail.com>
+Date: Sat, 24 Aug 2024 08:30:31 +0100
+Subject: [PATCH] Output import-relative paths in generated C code. (GH-6341)
+
+When cython is run on a file that is not in the current working directory,
+it outputs filepaths that are either absolute or are basenames.
+It is not good to output absolute paths in the generated C code and
+basenames mess up coverage measurement.
+
+Upstream-Status: Backport [20bceea6b19ffc2f65b9fba2e4f737f09e5a2b20]
+Signed-off-by: Ross Burton <ross.burton@arm.com>
+---
+ Cython/Compiler/ExprNodes.py  | 8 +++++++-
+ Cython/Compiler/ModuleNode.py | 9 ++++++---
+ 2 files changed, 13 insertions(+), 4 deletions(-)
+
+diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py
+index a6bb1688e..0fbb15368 100644
+--- a/Cython/Compiler/ExprNodes.py
++++ b/Cython/Compiler/ExprNodes.py
+@@ -21,6 +21,7 @@ import re
+ import sys
+ import copy
+ import os.path
++import pathlib
+ import operator
+ 
+ from .Errors import (
+@@ -10072,7 +10073,12 @@ class CodeObjectNode(ExprNode):
+         func_name = code.get_py_string_const(
+             func.name, identifier=True, is_str=False, unicode_value=func.name)
+         # FIXME: better way to get the module file path at module init time? Encoding to use?
+-        file_path = StringEncoding.bytes_literal(func.pos[0].get_filenametable_entry().encode('utf8'), 'utf8')
++        file_path = func.pos[0].get_filenametable_entry()
++        if os.path.isabs(file_path):
++            file_path = func.pos[0].get_description()
++        # Always use / as separator
++        file_path = pathlib.Path(file_path).as_posix()
++        file_path = StringEncoding.bytes_literal(file_path.encode('utf-8'), 'utf8')
+         file_path_const = code.get_py_string_const(file_path, identifier=False, is_str=True)
+ 
+         # This combination makes CPython create a new dict for "frame.f_locals" (see GH #1836).
+diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py
+index 43c6b5f07..8c29d6db7 100644
+--- a/Cython/Compiler/ModuleNode.py
++++ b/Cython/Compiler/ModuleNode.py
+@@ -13,6 +13,7 @@ from collections import defaultdict
+ import json
+ import operator
+ import os
++import pathlib
+ import re
+ import sys
+ 
+@@ -944,9 +945,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
+             for source_desc in code.globalstate.filename_list:
+                 file_path = source_desc.get_filenametable_entry()
+                 if isabs(file_path):
+-                    file_path = basename(file_path)  # never include absolute paths
+-                escaped_filename = file_path.replace("\\", "\\\\").replace('"', r'\"')
+-                escaped_filename = as_encoded_filename(escaped_filename)
++                    # never include absolute paths
++                    file_path = source_desc.get_description()
++                # Always use / as separator
++                file_path = pathlib.Path(file_path).as_posix()
++                escaped_filename = as_encoded_filename(file_path)
+                 code.putln('%s,' % escaped_filename.as_c_string_literal())
+         else:
+             # Some C compilers don't like an empty array
+-- 
+2.34.1
+
diff --git a/meta/recipes-devtools/python/python3-cython/0001-WIP-prefix-map.patch b/meta/recipes-devtools/python/python3-cython/0001-WIP-prefix-map.patch
deleted file mode 100644
index adc9463ffa7..00000000000
--- a/meta/recipes-devtools/python/python3-cython/0001-WIP-prefix-map.patch
+++ /dev/null
@@ -1,148 +0,0 @@ 
-From 4d1b7911372561b22e03c7f2b4ec807502b5b9c1 Mon Sep 17 00:00:00 2001
-From: Ross Burton <ross.burton@arm.com>
-Date: Mon, 4 Nov 2024 15:36:39 +0000
-Subject: [PATCH] WIP prefix map
-
-Upstream-Status: Inappropriate
-Signed-off-by: Ross Burton <ross.burton@arm.com>
----
- Cython/Compiler/CmdLine.py  | 9 ++++++++-
- Cython/Compiler/Main.py     | 9 +++++----
- Cython/Compiler/Options.py  | 1 +
- Cython/Compiler/Parsing.py  | 1 +
- Cython/Compiler/Scanning.py | 9 +++++++--
- 5 files changed, 22 insertions(+), 7 deletions(-)
-
-diff --git a/Cython/Compiler/CmdLine.py b/Cython/Compiler/CmdLine.py
-index 776636c..f5a7c79 100644
---- a/Cython/Compiler/CmdLine.py
-+++ b/Cython/Compiler/CmdLine.py
-@@ -74,6 +74,12 @@ class SetAnnotateCoverageAction(Action):
-         namespace.annotate = True
-         namespace.annotate_coverage_xml = values
- 
-+class SetPrefixMapAction(Action):
-+    def __call__(self, parser, namespace, values, option_string=None):
-+        mappings = getattr(namespace, self.dest, {})
-+        k, v = values.split("=", 1)
-+        mappings[k] = v
-+        setattr(namespace, self.dest, mappings)
- 
- def create_cython_argparser():
-     description = "Cython (https://cython.org/) is a compiler for code written in the "\
-@@ -157,9 +163,10 @@ def create_cython_argparser():
-                            'deduced from the import path if source file is in '
-                            'a package, or equals the filename otherwise.')
-     parser.add_argument('-M', '--depfile', action='store_true', help='produce depfiles for the sources')
-+    # TODO: add help
-+    parser.add_argument("--prefix-map", action=SetPrefixMapAction)
-     parser.add_argument('sources', nargs='*', default=[])
- 
--    # TODO: add help
-     parser.add_argument("-z", "--pre-import", dest='pre_import', action='store', type=str, help=SUPPRESS)
-     parser.add_argument("--convert-range", dest='convert_range', action='store_true', help=SUPPRESS)
-     parser.add_argument("--no-c-in-traceback", dest='c_line_in_traceback', action='store_false', help=SUPPRESS)
-diff --git a/Cython/Compiler/Main.py b/Cython/Compiler/Main.py
-index 80946c0..28cfe68 100644
---- a/Cython/Compiler/Main.py
-+++ b/Cython/Compiler/Main.py
-@@ -70,7 +70,7 @@ class Context(object):
-     language_level = None  # warn when not set but default to Py2
- 
-     def __init__(self, include_directories, compiler_directives, cpp=False,
--                 language_level=None, options=None):
-+                 language_level=None, prefix_map=None, options=None):
-         # cython_scope is a hack, set to False by subclasses, in order to break
-         # an infinite loop.
-         # Better code organization would fix it.
-@@ -83,6 +83,7 @@ class Context(object):
-         self.future_directives = set()
-         self.compiler_directives = compiler_directives
-         self.cpp = cpp
-+        self.prefix_map = prefix_map or {}
-         self.options = options
- 
-         self.pxds = {}  # full name -> node tree
-@@ -98,7 +99,7 @@ class Context(object):
-     @classmethod
-     def from_options(cls, options):
-         return cls(options.include_path, options.compiler_directives,
--                   options.cplus, options.language_level, options=options)
-+                   options.cplus, options.language_level, prefix_map=options.prefix_map, options=options)
- 
-     def set_language_level(self, level):
-         from .Future import print_function, unicode_literals, absolute_import, division, generator_stop
-@@ -259,7 +260,7 @@ class Context(object):
-                     rel_path = module_name.replace('.', os.sep) + os.path.splitext(pxd_pathname)[1]
-                     if not pxd_pathname.endswith(rel_path):
-                         rel_path = pxd_pathname  # safety measure to prevent printing incorrect paths
--                    source_desc = FileSourceDescriptor(pxd_pathname, rel_path)
-+                    source_desc = FileSourceDescriptor(pxd_pathname, rel_path, prefix_map=self.prefix_map)
-                     err, result = self.process_pxd(source_desc, scope, qualified_name)
-                     if err:
-                         raise err
-@@ -509,7 +510,7 @@ def run_pipeline(source, options, full_module_name=None, context=None):
-             rel_path = source  # safety measure to prevent printing incorrect paths
-     else:
-         rel_path = abs_path
--    source_desc = FileSourceDescriptor(abs_path, rel_path)
-+    source_desc = FileSourceDescriptor(abs_path, rel_path, prefix_map=context.prefix_map)
-     source = CompilationSource(source_desc, full_module_name, cwd)
- 
-     # Set up result object
-diff --git a/Cython/Compiler/Options.py b/Cython/Compiler/Options.py
-index 61950a7..cc52732 100644
---- a/Cython/Compiler/Options.py
-+++ b/Cython/Compiler/Options.py
-@@ -796,4 +796,5 @@ default_options = dict(
-     create_extension=None,
-     np_pythran=False,
-     legacy_implicit_noexcept=None,
-+    prefix_map=dict(pair.split("=", 1) for pair in os.environ.get("CYTHON_PREFIX_MAP", "").split()),
- )
-diff --git a/Cython/Compiler/Parsing.py b/Cython/Compiler/Parsing.py
-index 25c0de9..6c0eccf 100644
---- a/Cython/Compiler/Parsing.py
-+++ b/Cython/Compiler/Parsing.py
-@@ -2106,6 +2106,7 @@ def p_include_statement(s, ctx):
-             s.included_files.append(include_file_name)
-             with Utils.open_source_file(include_file_path) as f:
-                 source_desc = FileSourceDescriptor(include_file_path)
-+                print(f"TODO Cannot use prefix map on {include_file_path}")
-                 s2 = PyrexScanner(f, source_desc, s, source_encoding=f.encoding, parse_comments=s.parse_comments)
-                 tree = p_statement_list(s2, ctx)
-             return tree
-diff --git a/Cython/Compiler/Scanning.py b/Cython/Compiler/Scanning.py
-index 372392b..0fa3b30 100644
---- a/Cython/Compiler/Scanning.py
-+++ b/Cython/Compiler/Scanning.py
-@@ -195,7 +195,7 @@ class FileSourceDescriptor(SourceDescriptor):
-     optional name argument and will be passed back when asking for
-     the position()-tuple.
-     """
--    def __init__(self, filename, path_description=None):
-+    def __init__(self, filename, path_description=None, prefix_map={}):
-         filename = Utils.decode_filename(filename)
-         self.path_description = path_description or filename
-         self.filename = filename
-@@ -205,6 +205,7 @@ class FileSourceDescriptor(SourceDescriptor):
-         self.set_file_type_from_name(filename)
-         self._cmp_name = filename
-         self._lines = {}
-+        self.prefix_map = prefix_map
- 
-     def get_lines(self, encoding=None, error_handling=None):
-         # we cache the lines only the second time this is called, in
-@@ -243,7 +244,11 @@ class FileSourceDescriptor(SourceDescriptor):
-         return path
- 
-     def get_filenametable_entry(self):
--        return self.file_path
-+        entry = self.file_path
-+        for k, v in self.prefix_map.items():
-+            # TODO: should just replace the prefix
-+            entry = entry.replace(k, v)
-+        return entry
- 
-     def __eq__(self, other):
-         return isinstance(other, FileSourceDescriptor) and self.filename == other.filename
diff --git a/meta/recipes-devtools/python/python3-cython_3.0.11.bb b/meta/recipes-devtools/python/python3-cython_3.0.11.bb
index 020a8e7205c..2501e6ed232 100644
--- a/meta/recipes-devtools/python/python3-cython_3.0.11.bb
+++ b/meta/recipes-devtools/python/python3-cython_3.0.11.bb
@@ -7,7 +7,7 @@  SECTION = "devel/python"
 LICENSE = "Apache-2.0"
 LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=61c3ee8961575861fa86c7e62bc9f69c"
 
-SRC_URI += "file://0001-WIP-prefix-map.patch"
+SRC_URI += "file://0001-Output-import-relative-paths-in-generated-C-code.-GH.patch"
 SRC_URI[sha256sum] = "7146dd2af8682b4ca61331851e6aebce9fe5158e75300343f80c07ca80b1faff"
 
 inherit pypi setuptools3 cython