bpo-43682: Make staticmethod objects callable#25117
bpo-43682: Make staticmethod objects callable#25117vstinner merged 2 commits intopython:masterfrom vstinner:callable_staticmethod
Conversation
|
PR rebased to fix the enum doc fix from master. |
|
I rebased my PR and reverted the io and_pyio changes (they should be made in a separated PR). |
|
@serhiy-storchaka @gvanrossum @rhettinger: so, what do you think? this idea was rejected in 2015, but came back in 2021 and Guido likes the idea to make static methods callable. See also PR #25268 which makes staticmethod more "usable" to be used directly as a function. It's a tricky topic. We could also require to always use But sometimes, we need functions which can be used directly as method without staticmethod(), to mimick built-in function. Well see https://bugs.python.org/issue43682 and https://bugs.python.org/issue20309 discussions ;-) |
|
I like the idea. Why was it rejected in 2015? |
|
Victor want to replace In any case |
I solved this in PR #25268, did you see my PR?
See also https://bugs.python.org/issue43682#msg389907:
It's a similar issue than PEP 570 (positional-only arguments) solved for Python re-implementation of a C extension. We should either prevent C extensions to behave than Python, or we should allow pure Python code to behave the same. Here the issue is complex (changing built-in functions or Python functions to add/remove descriptor), and I propose to only change staticmethod(). In the whole stdlib, I'm only aware of io.open which is used sometimes directly to define a method (without |
|
I merged my PR #25268 and rebased this PR on top of it. By the way, just for consistency, should we also make class methods callable? I have no use case for that :-) |
|
By the way, just for consistency, should we also make class methods
callable? I have no use case for that :-)
I thought those are callable already.
|
|
Guido:
Me too, but hey, static methods and class methods are weird! It's only callable when it goes throught the descriptor! |
|
Well, ignore my idea of making class methods callable. It makes no sense since it doesn't pass the class in this case. Example: The last call fails because it doesn't go trought the descriptor, and so the class method doesn't get the class argument. Output: |
You should pass that in explicitly in that case. I guess calling |
gvanrossum
left a comment
There was a problem hiding this comment.
But please first fix the comment about class methods being callable.
Lib/test/test_decorators.py
Outdated
There was a problem hiding this comment.
Class methods aren't callable yet.
Static methods (@staticmethod) are now callable as regular functions.
|
I fixed test_pydoc which shows a nice enhancement of this PR ;-) With this PR, inspect.signature() works on a static method, and returns the same signature than the wrapped callable object. On Python 3.9 (and in master without this change), inspect.signature(wrapper) fails with "TypeError: <staticmethod...> is not a callable object". |
|
Thanks for the review @gvanrossum. |
|
It is possible to wrap a static method into a new static method, Moreover, I expect that most decorators have a similar issue. Maybe a linter or a debug check can warn on that, but I don't think that staticmethod() must raise an error or return the first (static method) wrapper unchanged. |
Static methods created by the @staticmethod decorator are now
callable as regular functions.
https://bugs.python.org/issue43682