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

@when does not play nicely with other decorators. #40

Open
flosincapite opened this issue Dec 8, 2020 · 3 comments
Open

@when does not play nicely with other decorators. #40

flosincapite opened this issue Dec 8, 2020 · 3 comments

Comments

@flosincapite
Copy link
Contributor

I would like to be able to do something like this:

@adventurelib.when("command")
@other_decorator
def command():
    pass

If I want other_decorator to capture the args passed to command for some reason, I have to implement other_decorator like this:

def other_decorator():
    def dec(func):
        def wrapped(*args, **kwargs):
            # do something with args, kwargs
            return func(*args, **kwargs)
        return wrapped
    return dec

However, adventurelib.when prevents this, since the signature of wrapped(*args, **kwargs) differs from the signature of command().

Ideally, the signature validation logic in _register would be able to detect that signatures are compatible, even if they're not identical. Failing that, can you add a mechanism to disable signature enforcement?

Also note that changing the order of decorators won't work, e.g.

@other_decorator
@when(...)
def command():
    ...

will not incorporate other_decorator into the registered function.

@flosincapite
Copy link
Contributor Author

For what it's worth, I developed a workaround, but it involves exec and is very, very ugly.

@edmw
Copy link

edmw commented May 8, 2024

In case this is still relevant: The wrapped function needs to be decorated with @functools.wraps(func) which makes the wrapper function to look like the wrapped function. That way, @when should not complain.

import functools

...

def other_decorator():
    def dec(func):
        @functools.wraps(func)
        def wrapped(*args, **kwargs):
            # do something with args, kwargs
            return func(*args, **kwargs)
        return wrapped
    return dec

@flosincapite
Copy link
Contributor Author

Thanks! That is much nicer than what I came up with 😅

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

No branches or pull requests

2 participants