Code Monkey home page Code Monkey logo

Comments (4)

smarie avatar smarie commented on June 26, 2024

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.

smarie avatar smarie commented on June 26, 2024

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.

smarie avatar smarie commented on June 26, 2024

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.

smarie avatar smarie commented on June 26, 2024

For the record - this dynamic function creation with possibility to change the signature is now in makefun.

from decorator.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.