This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author productivememberofsociety666
Recipients ncoghlan, productivememberofsociety666, r.david.murray, rhettinger
Date 2015-03-25.23:50:06
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1427327407.06.0.489640186048.issue23764@psf.upfronthosting.co.za>
In-reply-to
Content
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.
History
Date User Action Args
2015-03-25 23:50:07productivememberofsociety666setrecipients: + productivememberofsociety666, rhettinger, ncoghlan, r.david.murray
2015-03-25 23:50:07productivememberofsociety666setmessageid: <1427327407.06.0.489640186048.issue23764@psf.upfronthosting.co.za>
2015-03-25 23:50:07productivememberofsociety666linkissue23764 messages
2015-03-25 23:50:06productivememberofsociety666create