diff --git a/decopatch/main.py b/decopatch/main.py index 68200d1..611a3ec 100644 --- a/decopatch/main.py +++ b/decopatch/main.py @@ -1,4 +1,4 @@ -from makefun import with_signature, add_signature_parameters +from makefun import with_signature, add_signature_parameters, compile_fun from decopatch.utils_modes import SignatureInfo, make_decorator_spec from decopatch.utils_disambiguation import create_single_arg_callable_or_class_disambiguator, disambiguate_call, \ DecoratorUsageInfo, can_arg_be_a_decorator_target @@ -232,10 +232,6 @@ def create_no_args_decorator(decorator_function, if function_for_metadata is None: function_for_metadata = decorator_function - @with_signature(None, - func_name=function_for_metadata.__name__, - doc=function_for_metadata.__doc__, - module_name=function_for_metadata.__module__) def new_decorator(*_): """ Code for your decorator, generated by decopatch to handle the case when it is called without parenthesis @@ -254,6 +250,11 @@ def new_decorator(*_): raise TypeError("Decorator function '%s' does not accept any argument." "" % decorator_function.__name__) + new_decorator = compile_fun(except_names=('decorator_function', ))(new_decorator) + new_decorator = with_signature(None, + func_name=function_for_metadata.__name__, + doc=function_for_metadata.__doc__, + module_name=function_for_metadata.__module__)(new_decorator) return new_decorator @@ -293,10 +294,7 @@ def create_kwonly_decorator(sig_info, # type: SignatureInfo # The first argument is mandatory AND keyword. So we do not need to change the signature to be fully protected # indeed python will automatically raise a `TypeError` when users will use this decorator without parenthesis # or with positional arguments. - @with_signature(sig_info.exposed_signature, - func_name=function_for_metadata.__name__, - doc=function_for_metadata.__doc__, - modulename=function_for_metadata.__module__) + def new_decorator(*no_args, **kwargs): """ Code for your decorator, generated by decopatch to handle the case when it is called without parenthesis @@ -304,6 +302,12 @@ def new_decorator(*no_args, **kwargs): # this is a parenthesis call, because otherwise a `TypeError` would already have been raised by python. return with_parenthesis_usage(decorator_function, *no_args, **kwargs) + new_decorator = compile_fun(except_names=('decorator_function', ))(new_decorator) + new_decorator = with_signature(sig_info.exposed_signature, + func_name=function_for_metadata.__name__, + doc=function_for_metadata.__doc__, + modulename=function_for_metadata.__module__)(new_decorator) + return new_decorator elif sig_info.use_signature_trick: # no need to modify the signature, we will expose *args, **kwargs @@ -341,20 +345,30 @@ def create_general_case_decorator(sig_info, # type: SignatureInfo # - even if user did not provide them # - and even if user provided them as positional !! (except for var-positional and fuutre positional-only args) - @with_signature(None if sig_info.use_signature_trick else sig_info.exposed_signature, - func_name=function_for_metadata.__name__, - doc=function_for_metadata.__doc__, - module_name=function_for_metadata.__module__) + # todo since the symbols are not in this module `compile_fun` does not compile them yet + # see https://github.com/smarie/python-makefun/pull/53 + call_in_appropriate_mode2 = compile_fun(call_in_appropriate_mode) + disambiguate_call2 = compile_fun(disambiguate_call) + def new_decorator(*args, **kwargs): """ Code for your decorator, generated by decopatch to handle the case when it is called without parenthesis """ # disambiguate dk = DecoratorUsageInfo(sig_info, args, kwargs) - disambiguation_result = disambiguate_call(dk, disambiguator) + disambiguation_result = disambiguate_call2(dk, disambiguator) # call - return call_in_appropriate_mode(impl_function, dk, disambiguation_result) + return call_in_appropriate_mode2(impl_function, dk, disambiguation_result) + + new_decorator = compile_fun(except_names=('impl_function', 'custom_disambiguator', 'enable_stack_introspection', + 'disambiguator', 'is_class_decorator', 'is_function_decorator', + 'signature_knowledge'))(new_decorator) + + new_decorator = with_signature(None if sig_info.use_signature_trick else sig_info.exposed_signature, + func_name=function_for_metadata.__name__, + doc=function_for_metadata.__doc__, + module_name=function_for_metadata.__module__)(new_decorator) # trick to declare that our true signature is different than our actual one if sig_info.use_signature_trick: