Comments (4)
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, test_func
). Therefore these test functions can add the special argument 'requests' in their signature if they wish pytest to inject that object into them. But they are not obliged to, they can also live without it.
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 decorate
method to add an additional_args
argument (for the record, decorate
is the single method I always use when I use your package - I find it handy and simple to use. I then create the decorator itself 'by hand' leveraging it).
# 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'])
from decorator.
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
from decorator.
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 decorate
method, so that the behaviour is consistent whatever the usage case: the signature of the caller provided by the user should always be
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 f(*args, **kwargs)
from decorator.
For the record - this dynamic function creation with possibility to change the signature is now in makefun.
from decorator.
Related Issues (20)
- 5.0.9: sphinx 4.x warnings HOT 3
- pylint warning W1113: keyword-arg-before-vararg HOT 1
- Regression in 5.1.0 - decorator.contextmanager no longer compat with contextlib.contextmanager HOT 4
- `FunctionMaker.create()` fails when given a function definition with a return type annotation. HOT 1
- Functionmaker.create (from doc example) fails with kwarg-only functions HOT 6
- `FunctionMaker.create` raises unexpected SyntaxError when return is present as substring for async function
- How to make `@decorator` with other decorators? HOT 3
- TypeError: missing 1 required positional argument HOT 1
- <=3.4.2 can't be installed with modern setuptools HOT 2
- Continuous fuzzing by way of OSS-Fuzz
- compatibility issue with kwargs HOT 2
- Not preserving low level signature metadada HOT 1
- decorator whether to support decorator partial functions?
- Confusion about license using HOT 1
- Making __name__ optional attribute of decorated-function if underlying function is missing it. HOT 3
- Compatibility with Python 3.12 - RuntimeError: There is no current event loop in thread 'MainThread'.
- Unable to pull 4.4.2 from the repo only pulls in 4.2.1 HOT 1
- [BUG] kwargs are not respected HOT 3
- Create SECURITY.md
- Create a decorator for both sync and async function HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from decorator.