Repository navigation
Closed
Labels
docsDocumentation in the Doc dirDocumentation in the Doc dirtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Description
Bug report
Bug description:
Since #106311 its documented in the inspect.signature() sphinx docs as:
"If the passed object has a __signature__ attribute, this function returns it without further computations."
That looks correct per PEP 362, see the implementation section. But actual code logic goes far away from this simple description:
Lines 2549 to 2562 in 8e8ab75
| if sig is not None: | |
| # since __text_signature__ is not writable on classes, __signature__ | |
| # may contain text (or be a callable that returns text); | |
| # if so, convert it | |
| o_sig = sig | |
| if not isinstance(sig, (Signature, str)) and callable(sig): | |
| sig = sig() | |
| if isinstance(sig, str): | |
| sig = _signature_fromstr(sigcls, obj, sig) | |
| if not isinstance(sig, Signature): | |
| raise TypeError( | |
| 'unexpected object {!r} in __signature__ ' | |
| 'attribute'.format(o_sig)) | |
| return sig |
Either we should document this properly (then this is a documentation issue). Or we could change the code and remove undocumented logic. As this attribute was documented recently, I'll suggest the second option.
CPython versions tested on:
CPython main branch
Operating systems tested on:
No response
Linked PRs
- gh-115937: remove extra processing for the __signature__ attribute #115984
- gh-115937: Remove implementation details from inspect.signature() docs #116086
- [3.12] gh-115937: Remove implementation details from inspect.signature() docs (GH-116086) #116106
- [3.11] gh-115937: Remove implementation details from inspect.signature() docs (GH-116086) #116107
Reacted by Gouvernathor and Ellis Breen
Metadata
Metadata
Assignees
Labels
docsDocumentation in the Doc dirDocumentation in the Doc dirtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Activity
erlend-aasland commentedon Feb 26, 2024
Instead of rewriting the implementation in prose, another option is to word the recently added sentence more vague.
Also, in the case of discrepancies between docs and implementation, we (almost) never align the code with the docs, as that in most cases is bound to be a breaking change.
Gouvernathor commentedon Feb 27, 2024
Explaining the current implementation as presented here, while it may not be the best choice for other reasons, is not very hard to explain in a simple manner.
__signature__takes either :inspect.signature then makes a signature object out of it.
What would be weird though, is that there would be no documented way of turning a string like
"(self, /, *args)"into a signature object directly, but there would be a roundabout way by setting that string to be the__signature__parameter of a random object and passing that to inspect.signature.skirpichev commentedon Feb 27, 2024
Isn't documentation expected to be as precise as possible?
Perhaps, this case is a special one.
__signature__attribute and if it is notNone- return it)For a background, new logic was introduced recently (since 3.12) in #100039. Maybe @ethanfurman could explain why parsing text signatures was chosen instead of using the Signature class in a pure-Python code? Recent discussion (https://discuss.python.org/t/43914/) reveals, that the
__text_signature__-like interface, probably, is a bad one even for extensions.This forces us to document the format for the
__text_signature__, isn't? It worth to note, that repr/str formats for the Signature are different from that one.hugovk commentedon Feb 27, 2024
No, the style guide advises economy of expression:
pythongh-115937: remove extra processing for the __signature__ attribute
skirpichev commentedon Feb 27, 2024
Hmm, I think we have a working alternative for #100168, that has no need in support callables or parsing text. There is also type check, added to solve #66000. I think, adding a setter method in typeobject.c might be an alternative.
That's hardly the case. Missing parts aren't just "corner cases" or something "complex". Logic is simple. Just... undocumented.
Gouvernathor commentedon Feb 27, 2024
I think that's what we should ascertain in the first place.
I agree with Hugo -it seems- that documenting the behavior in full details is not always the best solution, and I think that's especially true here. For now, the 100039 behavior is undocumented and while it is explainable in a simple way, it may not be something we want to commit to in the long-term.
Also, I'm sorry to say that about something that has been merged and publiqhed as part of a full Release (3.12 it seems), but this evolution is a breaking change, which goes against a behavior that has worked since the beginning I believe, which was introduced in a PEP, and whose proper documentation was backported. #115984 needs to be considered as a solution and as things currently stand, that's the way out I'm supporting.Edit: it's actually not a breaking change, since a type check on
__signature__dates back from 2014. But after considering the single-use context it was added for, I even more strongly agree with reverting it, for two reasons:__text_signature__, if we want it to be more workable that's the one that should be changed, not__signature____signature__contains a callable, I wouldn't expect it to return a signature object when called with no arguments (?), I would only assume the signature function to be told to return the signature of that callable. It may pose other problems (loop recursion being one of them), but in any case I don't think the no-param callable use case makes sense.skirpichev commentedon Feb 27, 2024
BTW, #115984 is in a simplest version. We could do proper deprecation for changes, introduced in the 3.12 release.
pythongh-115937: Remove implementation details from inspect.signature…
gh-115937: Remove implementation details from inspect.signature() docs (
pythongh-115937: Remove implementation details from inspect.signature…
pythongh-115937: Remove implementation details from inspect.signature…
[3.12] gh-115937: Remove implementation details from inspect.signatur…
[3.11] gh-115937: Remove implementation details from inspect.signatur…
skirpichev commentedon Feb 29, 2024
@erlend-aasland, could you, please remove "bug" label? Apparently, parsing a string, taken from the
__signature__doesn't considered as an issue by CPython devs.pythongh-115937: Remove implementation details from inspect.signature…
pythongh-115937: Remove implementation details from inspect.signature…
pythongh-115937: Remove implementation details from inspect.signature…