Skip to content
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

Provide an easier way to wrap a function whatever its mode (regular, generator, or generator coroutine) #19

Open
smarie opened this issue Mar 5, 2019 · 1 comment
Labels
enhancement New feature or request

Comments

@smarie
Copy link
Owner

smarie commented Mar 5, 2019

In many cases when we create function wrappers, we would like to have a single way to write the wrapper rather than handling both generator and regular modes with a if/else.

A good illustration is provided below:

https://github.com/smarie/python-pytest-harvest/blob/master/pytest_harvest/fixture_cache.py#L193

Maybe we could add a multi_mode_handler flag ? Setting it to True would require the handler to be written in a way that is independent from the wrapped mode (to be found... maybe a coroutine ?).

@smarie smarie added the enhancement New feature or request label Mar 5, 2019
@smarie
Copy link
Owner Author

smarie commented Mar 5, 2019

I propose to add a mode argument instead, and to provide a helper companion as_generator function.

def create_wrapper(f):
 
    # use the helper to always have a generator
    genf = as_generator(f)

    @with_signature(f, mode=f)
    def my_handler( *args, **kwargs):
        # <init code>
        gen = genf(*args, **kwargs)
        for res in gen:
             # <intermediate code>
             yield res  # or yield anything else
        # <termination code>

    return my_handler

This would do the trick.

  • mode=f indicates that the generated function has the same mode than f (generator if generator, etc.). In that case the handler has to be itself a generator (nothing else is supported).
  • as_generator(f) is used to turn f into a generator if it is not already the case

The code above would work if foo is a normal function or a generator:

def foo(a):
    return "hello"

create_wrapper(foo)  # should be a normal function

def foo_g(a):
    yield "hello"
    yield "again"

create_wrapper(foo)  # should be a generator

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant