I’ve updated this based on @KevinMGranger and @hwayne’s comments.
Once again, lobste.rs comments have helped make my writing better. Starting to be tempted to post thing first here, wait for comments, update appropriately, and only then post elsewhere.
The complaint about the signature was fixed in python3.4.
Thanks for correction!. I wonder why I didn’t catch that when writing the post, I was using Python 3.5. Probably screwed up reloading the code or something. Will update post after dinner.
add = synchronized(add) doesn’t preserve the docstring either, so at worst decorators are API-neutral.
add = synchronized(add)
The point, which I will try to make more explicit, is that decorators are a wasted opportunity: it could’ve done the right thing in the language level, but instead it forces library code to fix the edge cases the language doesn’t handle for you.
I can see two reasons why the current behavior is preferable:
Edit: another case is if you explicitly want to do something with the docstring, like make a depreciated decorator. This would be a lot harder if decorators automatically used the wrapped functions attributes.
More broadly: decorators were added in 2.4. functools.wraps was added in 2.6. So fundamentally the use case of callers wasn’t addressed by Python all until then.