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
bpo-43857: Improve the AttributeError message when deleting a missing attribute #25424
Conversation
This PR is stale because it has been open for 30 days with no activity. |
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.
I agree with this idea. Could you add a NEWS entry and a unit test that exercises this message?
(I promise I'm not stalking you, I just opened page 24 of the open PRs and found this one :) .)
Thanks @JelleZijlstra, but please don’t merge right now as some tests are failing. I am going to work on it in the next few hours. I’ll let you know when it works. |
Not only objects but also type objects have inconsistent $ python3
Python 3.9.12 (main, Mar 26 2022, 15:52:10)
[Clang 13.0.0 (clang-1300.0.29.30)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> class A: pass
...
>>> A.x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: type object 'A' has no attribute 'x'
>>> del A.x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: x
>>> A().x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'A' object has no attribute 'x'
>>> del A().x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: x Compare that with PyPy for which the messages are consistent (well almost, $ pypy3
Python 3.7.13 (7e0ae751533460d5f89f3ac48ce366d8642d1db5, Apr 26 2022, 09:31:20)
[PyPy 7.3.9 with GCC Apple LLVM 13.0.0 (clang-1300.0.29.30)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>> class A: pass
>>>>
>>>> A.x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: type object 'A' has no attribute 'x'
>>>> del A.x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'type' object has no attribute 'x'
>>>> A().x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'A' object has no attribute 'x'
>>>> del A().x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'A' object has no attribute 'x' Following @markshannon’s PR #28802 for Python 3.11, the message fix of this line in Objects/object.c provided at the early stage of this PR no longer works for objects but only for type objects: if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
- PyErr_SetObject(PyExc_AttributeError, name);
+ PyErr_Format(PyExc_AttributeError,
+ "'%.100s' object has no attribute '%U'",
+ tp->tp_name, name); To fix the message for objects, we should also update this line in Objects/dictobject.c: - PyErr_SetObject(PyExc_AttributeError, name);
+ PyErr_Format(PyExc_AttributeError,
+ "'%.100s' object has no attribute '%U'",
+ Py_TYPE(obj)->tp_name, name); That way we get the same messages as in PyPy. Finally to solve the last message inconsistency ( - if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
- PyErr_SetObject(PyExc_AttributeError, name);
+ if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) {
+ if (PyType_IsSubtype(tp, &PyType_Type)) {
+ PyErr_Format(PyExc_AttributeError,
+ "type object '%.50s' has no attribute '%U'",
+ ((PyTypeObject*)obj)->tp_name, name);
+ }
+ else {
+ PyErr_Format(PyExc_AttributeError,
+ "'%.100s' object has no attribute '%U'",
+ tp->tp_name, name);
+ }
+ } |
@JelleZijlstra Done, all tests are passing. The PR is ready. |
Thanks again @JelleZijlstra!
No worries. And even if you were stalking my PRs I would not complain, quite the opposite =) |
https://bugs.python.org/issue43857
#88023