Commit c9a42878 authored by da-woods's avatar da-woods Committed by GitHub

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.
parent 12d17bb0
......@@ -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))
......
......@@ -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):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment