-
Notifications
You must be signed in to change notification settings - Fork 107
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Possibility to add additional arguments to the decorated function #55
Comments
Following conversation in #58 here is hopefully a simpler explanation: Basically my decorator wraps user-created test functions that are compliant with pytest (in the example below, The issue is that in my function wrapper, I absolutely need that 'requests' object to be injected - indeed I use it in the wrapper that I create. So I have to add the argument to the signature if it is not already present, or leave it if it is. For this purpose I improved your # The function to wrap is 'test_func'. We first extract its signature
f_sig = signature(test_func)
# -- first define the logic once and for all
def _inner_logic(f, request, *args, **kwargs):
# ... (my business here)
# -- then define the appropriate function wrapper according to wrapped function signature
if 'request' not in f_sig.parameters:
# easy: we can add 'request' explicitly in our signature
def dependency_mgr_wrapper(f, request, *args, **kwargs):
return _inner_logic(f, request, *args, **kwargs)
else:
# harder: we have to retrieve the value for request from args. Thanks, inspect package !
def dependency_mgr_wrapper(f, *args, **kwargs):
request = f_sig.bind(*args, **kwargs).arguments['request']
return _inner_logic(f, request, *args, **kwargs)
# Finally wrap the test function and add the 'request' argument
wrapped_test_function = decorate(test_func, dependency_mgr_wrapper, additional_args=['request']) |
Note: I'm also quite sure that one day someone will come up with the need to remove an argument too :) but let's leave it for later |
I found an even better way to use this. With the new PR code, the above example would be much simpler to write: def dependency_mgr_wrapper(f, request, *args, **kwargs):
# ... (my business here)
# Finally wrap the test function and add the 'request' argument
wrapped_test_function = decorate(test_func, dependency_mgr_wrapper, additional_args=['request']) Basically I put the signature checking steps in the def caller(f, <all named additional args in order>, *args, **kwargs): If some additional args are already part of the wrapped function signature they will arrive twice. That way it is easy for users to call the inner function with all its required arguments, by calling |
For the record - this dynamic function creation with possibility to change the signature is now in makefun. |
Hi there,
I'm a big fan of your library and I used it in many of mine :).
I recently came in pytest-steps with the need to
The use-case is that the decorated function is a pytest test function, that can or can not already have the "request" argument in its signature, but I need the wrapped function to have it always. I came up with the following hack, maybe this is something you would be interested in ?
Here is how I use it in a complex case. One additional argument
________step_name_
is guaranteed to not be in the function signature, while the 'request' argument may or may not be thereIf you think that this feature is interesting, I can make a Pull Request.
The text was updated successfully, but these errors were encountered: