productivememberofsociety666 added the comment:
You're probably right and it's next to impossible to implement what I want in a
clean manner. I'll get back to that at the end, but first for completeness's
sake two examples to illustrate what this issue is even about.
````
import functools
def wrapper(func):
@functools.wraps(func)
def new_func(*args, **kwargs):
pass
return new_func
def to_be_wrapped(a):
pass
wrapped = wrapper(to_be_wrapped)
wrapped(1) # Ok
wrapped(1, 2, 3) # Also ok, but shouldn't be! Should raise TypeError
````
The second call to wrapped() should fail because it's supposed to be a wrapper
around to_be_wrapped(), which only takes 1 argument. But it succeeds because
functools.wraps only changes "superficial" function attributes such as its
signature or docstring. This creates a mismatch between expected and actual
behaviour of wrapped().
Contrast this with how it works when using the decorator package I mentioned:
````
import decorator
def to_be_wrapped(x):
print("f(x) called")
pass
def _wrapper(func, *args, **kwargs):
# Put actual functionality of your decorator here
pass
def wrapper(func):
return decorator.decorator(_wrapper, func)
wrapped = wrapper(to_be_wrapped)
wrapped(1) # Ok, because to_be_wrapped takes exactly 1 argument
wrapped(1, 2, 3) # raises TypeError for too many arguments, as it should
````
Like I said, the details of how it is used are different from those of
functools.wraps. But the important thing is that, at the end, wrapped()'s
argspec matches that of to_be_wrapped() and an appropriate error is raised by
the second call.
Note that this does NOT work via propagation from a call to to_be_wrapped() or
anything of the sort, as can be verified by the lack of output to stdout.
Now, the only problem is: I had a look at how this is achieved in the decorator
package's source code and if I understand it correctly, they are doing some
nasty nasty things with exec() to create a function with an argspec of their
choosing at runtime. If this is in fact the only way to do it, I agree that it
has no place in the standard library and should only be available via 3rd party
libraries. Sorry for wasting your time then.
----------
_______________________________________
Python tracker <[email protected]>
<http://bugs.python.org/issue23764>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com