diff options
author | da-woods <dw-git@d-woods.co.uk> | 2020-05-17 18:31:12 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-05-17 19:31:12 +0200 |
commit | 6313c86737f8f8a795e356ae6da0bc59fb68b159 (patch) | |
tree | c1c974c0b4615a42d35fdb6137febb6ae51c09a3 | |
parent | 83ac1a27735d562baf58f3577bc933ee7cbb8c29 (diff) | |
download | cython-6313c86737f8f8a795e356ae6da0bc59fb68b159.tar.gz |
Ensure utility code keeps the directives that it was compiled with (GH-3615)
When it's merged into the main module, wrap it in a CompilerDirectivesNode.
-rw-r--r-- | Cython/Compiler/ModuleNode.py | 8 | ||||
-rw-r--r-- | Cython/Compiler/Pipeline.py | 3 | ||||
-rw-r--r-- | tests/memoryview/memoryview_no_binding_T3613.pyx | 21 |
3 files changed, 30 insertions, 2 deletions
diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py index ea003bf31..4023a1dde 100644 --- a/Cython/Compiler/ModuleNode.py +++ b/Cython/Compiler/ModuleNode.py @@ -87,7 +87,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): child_attrs = ["body"] directives = None - def merge_in(self, tree, scope, merge_scope=False): # Merges in the contents of another tree, and possibly scope. With the # current implementation below, this must be done right prior @@ -123,6 +122,13 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): self.scope.merge_in(scope) + def with_compiler_directives(self): + # When merging a utility code module into the user code we need to preserve + # the original compiler directives. This returns the body of the module node, + # wrapped in its set of directives. + body = Nodes.CompilerDirectivesNode(self.pos, directives=self.directives, body=self.body) + return body + def analyse_declarations(self, env): if has_np_pythran(env): Pythran.include_pythran_generic(env) diff --git a/Cython/Compiler/Pipeline.py b/Cython/Compiler/Pipeline.py index 5194c3e49..5bab4dbdb 100644 --- a/Cython/Compiler/Pipeline.py +++ b/Cython/Compiler/Pipeline.py @@ -128,7 +128,8 @@ def inject_utility_code_stage_factory(context): module_node.scope.utility_code_list.append(dep) tree = utilcode.get_tree(cython_scope=context.cython_scope) if tree: - module_node.merge_in(tree.body, tree.scope, merge_scope=True) + module_node.merge_in(tree.with_compiler_directives(), + tree.scope, merge_scope=True) return module_node return inject_utility_code_stage diff --git a/tests/memoryview/memoryview_no_binding_T3613.pyx b/tests/memoryview/memoryview_no_binding_T3613.pyx new file mode 100644 index 000000000..1c736359e --- /dev/null +++ b/tests/memoryview/memoryview_no_binding_T3613.pyx @@ -0,0 +1,21 @@ +# mode: compile +# tag: memoryview + +# cython: binding=False + +# See GH 3613 - when memoryviews were compiled with binding off they ended up in an +# inconsistent state where different directives were applied at different stages +# of the pipeline + +import cython + +def f(double[:] a): + pass + +@cython.binding(False) +def g(double[:] a): + pass + +@cython.binding(True) +def h(double[:] a): + pass |