Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 29 additions & 15 deletions decopatch/main.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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


Expand Down Expand Up @@ -293,17 +294,20 @@ 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
"""
# 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
Expand Down Expand Up @@ -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:
Expand Down