Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 34k
bpo-46730: Add more info to @property AttributeError messages#31311
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Conversation
Alex-Blade commented Feb 13, 2022 • edited by bedevere-bot
Loading Uh oh!
There was an error while loading. Please reload this page.
edited by bedevere-bot
Uh oh!
There was an error while loading. Please reload this page.
The property decorator raises AttributeErrors with messages that neither help to identify the problem nor lead to a possible solution. This commit proposes changes in error messages to address the issue.
the-knights-who-say-ni commented Feb 13, 2022
Hello, and thanks for your contribution! I'm a bot set up to make sure that the project can legally accept this contribution by verifying everyone involved has signed the PSF contributor agreement (CLA). CLA MissingOur records indicate the following people have not signed the CLA: For legal reasons we need all the people listed to sign the CLA before we can look at your contribution. Please follow the steps outlined in the CPython devguide to rectify this issue. If you have recently signed the CLA, please wait at least one business day You can check yourself to see if the CLA has been received. Thanks again for the contribution, we look forward to reviewing it! |
Alex-Blade commented Feb 13, 2022
Now, there are a few things to discuss: I absolutely agree with it, since it was the initial idea, however when trying it I've found out that the testing system expects the name of the attribute to be at the end: So in order to make the message in the proposed format, this should be subject to change as well. P.S. I have signed the CLA, just haven't got the response yet. |
sweeneyde commented Feb 13, 2022 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
I think those test cases can be adjusted appropriately to match the behavior.
Yep, it usually takes a business day or two to go through. I also think it would be useful to include the type name in the message: Compare to the current behavior for other attributes in other situations: I believe this is the relevant code for that case: Lines 1405 to 1407 in 6331c08
|
TeamSpen210 commented Feb 13, 2022
Using |
sweeneyde commented Feb 13, 2022 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
Isn't >>>fromcollectionsimportdefaultdict>>>dict.popisdefaultdict.popTrue>>>dd=defaultdict() >>>dd.pop=42Traceback (mostrecentcalllast): File"<stdin>", line1, in<module>AttributeError: 'collections.defaultdict'objectattribute'pop'isread-onlyAnd there are parallel situations like this: >>>classBase: ... def__float__(self): ... returnNone ... >>>classSub(Base): ... pass ... >>>float(Sub()) Traceback (mostrecentcalllast): File"<pyshell#28>", line1, in<module>float(Sub()) TypeError: Sub.__float__returnednon-float (type NoneType)My thinking is that specifying the type is helpful for identifying which objects in the client code are being used and which line to look at, not where the implementation happens to live: >>>classBaseThingDoer: ... @property ... defattr(self): ... pass>>># ( ... Suppose lots of other concrete implementations ... )>>>classSpecialThingDoer(BaseThingDoer): ... pass>>>thing=SpecialThingDoer() # These two lines are the lines I'm looking at.>>>thing.attr=42# I think I would expect the error message to say SpecialThingDoer.AttributeError: can't set attribute 'attr'It's safer and easier to implement if I understand right. |
This is an improvement to the initial patch for the bpo-46730. It adds additional information on class that owns the property that caused an AttributeError.
Alex-Blade commented Feb 13, 2022
@sweeneyde, I think your idea doesn't solve the problem of "which line to look at" because of subclasses. classA: @propertydefa(self) ->int: returnNoneclassB(A): @propertydefb(self) ->int: returnNoneclassC(B): pass>>>A().a=2Traceback (mostrecentcalllast): File"<stdin>", line1, in<module>AttributeError: property'a'originatingfrom'A'hasnosetter>>>B().a=2Traceback (mostrecentcalllast): File"<stdin>", line1, in<module>AttributeError: property'a'originatingfrom'A'hasnosetter>>>B().b=2Traceback (mostrecentcalllast): File"<stdin>", line1, in<module>AttributeError: property'b'originatingfrom'B'hasnosetter>>>C().b=2Traceback (mostrecentcalllast): File"<stdin>", line1, in<module>AttributeError: property'b'originatingfrom'B'hasnosetterFew points to discuss though:
|
Alex-Blade commented Feb 13, 2022
Oh, actually I think I've misunderstood your comment. To the example of Perhaps this could be resolved by choosing the sentence for the error message:
This one implies that the problem is within the current object and thus
And this one implies that the property is the problem and it should be fixed wherever it's defined - in I don't see any convenience difference, however implementing the first one requires less changes, resolves the issue with sketchiness of the first attempt and removes unnecessary size increase. Seems like I should retry it :) |
sweeneyde commented Feb 14, 2022 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
I think I agree with lots of your assessments -- either type might be more helpful in different circumstances. But for simplicity of implementation and consistency with other similar situations, I'd prefer to just display the type of I don't know what the best verbiage is to convey that that's what is being displayed, but I agree that some word choices are more suggestive of that than others. Maybe something like what Bruce Leban suggested on Python-Ideas, or Another reason to avoid adding extra state to the property is that the same property object can theoretically live in multiple classes: |
TeamSpen210 commented Feb 14, 2022
The misleading behaviour when a property is in two classes isn't really solvable, and also applies if you put it under a different attribute name - functions have the same issue. Since the decorator methods create copies, it's probably not too big of an issue. |
sweeneyde commented Feb 14, 2022
I'm suggesting that it is "solvable" in one sense: just don't store inside a |
Alex-Blade commented Feb 14, 2022 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
I've assessed all variants and came to a conclusion that a combination of all our suggestions would work great: classA: @propertydefa(self) ->int: returnNoneclassB(A): @propertydefb(self) ->int: returnNoneB().b=2Traceback (mostrecentcalllast): File"<stdin>", line1, in<module>AttributeError: property'b'inobjectof type 'B'hasnosetterB().a=2Traceback (mostrecentcalllast): File"<stdin>", line1, in<module>AttributeError: property'a'inobjectof type 'B'hasnosetter
UPD. And yes, it's based on qualname |
sweeneyde left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is mostly looking good, just some minor nits remaining.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
bedevere-bot commented Feb 14, 2022
A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated. Once you have made the requested changes, please leave a comment on this pull request containing the phrase |
Uh oh!
There was an error while loading. Please reload this page.
Properly escape dot character and return `_format_exc_msg` function to its initial state.
Alex-Blade commented Feb 14, 2022
I have made the requested changes; please review again P.S. Seems like I also should make a NEWS entry, right? |
bedevere-bot commented Feb 14, 2022
Thanks for making the requested changes! @sweeneyde: please review the changes made to this pull request. |
sweeneyde commented Feb 14, 2022
Yes, please do. You can either click on "Details" of the bevedere/news check or you can use blurb |
sweeneyde left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. I'll leave it open for a day or so to see if there are any more comments, but after that, I can merge.
If you want, you can add your name to MISC/ACKS as well.
Uh oh!
There was an error while loading. Please reload this page.
sweeneyde commented Feb 15, 2022
Shouldn't "object %R" be "%R object"? 42 is an int object, not object int. |
Alex-Blade commented Feb 15, 2022
Oh, that's what caused my confusion and I couldn't understand it! :) |
Alex-Blade commented Feb 15, 2022
@eryksun, what do you think now? |
eryksun commented Feb 15, 2022
I'm okay with either "property %R of %R objects" or "property %R of %R object". I prefer the former. It's common in English when generalizing to a category or class of things, unless that class is already a mass noun. You can see this style used in "Objects/descrobject.c":
|
sweeneyde commented Feb 15, 2022
Reasonable people will disagree, but the pattern I see is that usages of the plural as in "{p} for{T} objects" tend to be situations where the descriptor knows what type it's supposed to apply to, but there is no well-defined notion of "the associated type" for property objects, since you can do In contrast, other error messages tend to use the singular "object" when they display the type of the particular object in question (as this PR is set to do): |
Uh oh!
There was an error while loading. Please reload this page.
tiran commented Feb 17, 2022
The commit introduced a reference leak and code was missing checks for NULL. #31389 addresses both problems. |
The property decorator raises AttributeErrors with messages
that neither help to identify the problem nor lead to a possible solution.
This PR proposes changes in error messages to address the issue.
https://bugs.python.org/issue46730