summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorda-woods <dw-git@d-woods.co.uk>2021-07-20 08:31:09 +0100
committerGitHub <noreply@github.com>2021-07-20 09:31:09 +0200
commitc9a428789ff5fe919d21fbc238a4c8504161ad24 (patch)
tree44f34ebf7c345d2354c7cd0133b9fc88a7639d23
parent12d17bb0e68e238fbd6c27189025782fd26e8d47 (diff)
downloadcython-c9a428789ff5fe919d21fbc238a4c8504161ad24.tar.gz
Prevent C++ coercions from picking up user-set directives (GH-4206)
For example, if they're called on entry/exit to a decorated function they pick up the directives. They should really be independent of most user defined settings, especially local ones.
-rw-r--r--Cython/Compiler/PyrexTypes.py8
-rw-r--r--Cython/Compiler/UtilityCode.py21
2 files changed, 24 insertions, 5 deletions
diff --git a/Cython/Compiler/PyrexTypes.py b/Cython/Compiler/PyrexTypes.py
index 5d0ecd1ba..d36e19950 100644
--- a/Cython/Compiler/PyrexTypes.py
+++ b/Cython/Compiler/PyrexTypes.py
@@ -3808,9 +3808,8 @@ class CppClassType(CType):
'type': self.cname,
})
# Override directives that should not be inherited from user code.
- # TODO: filter directives with an allow list to keep only those that are safe and relevant.
- directives = dict(env.directives, cpp_locals=False)
from .UtilityCode import CythonUtilityCode
+ directives = CythonUtilityCode.filter_inherited_directives(env.directives)
env.use_utility_code(CythonUtilityCode.load(
cls.replace('unordered_', '') + ".from_py", "CppConvert.pyx",
context=context, compiler_directives=directives))
@@ -3855,10 +3854,9 @@ class CppClassType(CType):
'maybe_unordered': self.maybe_unordered(),
'type': self.cname,
})
- # Override directives that should not be inherited from user code.
- # TODO: filter directives with an allow list to keep only those that are safe and relevant.
- directives = dict(env.directives, cpp_locals=False)
from .UtilityCode import CythonUtilityCode
+ # Override directives that should not be inherited from user code.
+ directives = CythonUtilityCode.filter_inherited_directives(env.directives)
env.use_utility_code(CythonUtilityCode.load(
cls.replace('unordered_', '') + ".to_py", "CppConvert.pyx",
context=context, compiler_directives=directives))
diff --git a/Cython/Compiler/UtilityCode.py b/Cython/Compiler/UtilityCode.py
index c58c8623c..870abf3e5 100644
--- a/Cython/Compiler/UtilityCode.py
+++ b/Cython/Compiler/UtilityCode.py
@@ -227,6 +227,27 @@ class CythonUtilityCode(Code.UtilityCodeBase):
return original_scope
+ @staticmethod
+ def filter_inherited_directives(current_directives):
+ """
+ Cython utility code should usually only pick up a few directives from the
+ environment (those that intentionally control its function) and ignore most
+ other compiler directives. This function provides a sensible default list
+ of directives to copy.
+ """
+ from .Options import _directive_defaults
+ utility_code_directives = dict(_directive_defaults)
+ inherited_directive_names = (
+ 'binding', 'always_allow_keywords', 'allow_none_for_extension_args',
+ 'auto_pickle', 'ccomplex',
+ 'c_string_type', 'c_string_encoding',
+ 'optimize.inline_defnode_calls', 'optimize.unpack_method_calls',
+ 'optimize.unpack_method_calls_in_pyinit', 'optimize.use_switch')
+ for name in inherited_directive_names:
+ if name in current_directives:
+ utility_code_directives[name] = current_directives[name]
+ return utility_code_directives
+
def declare_declarations_in_scope(declaration_string, env, private_type=True,
*args, **kwargs):