From c9a428789ff5fe919d21fbc238a4c8504161ad24 Mon Sep 17 00:00:00 2001 From: da-woods Date: Tue, 20 Jul 2021 08:31:09 +0100 Subject: 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. --- Cython/Compiler/PyrexTypes.py | 8 +++----- Cython/Compiler/UtilityCode.py | 21 +++++++++++++++++++++ 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): -- cgit v1.2.1