bpo-43857: Improve the AttributeError message when deleting a missing attribute#25424
bpo-43857: Improve the AttributeError message when deleting a missing attribute#25424JelleZijlstra merged 13 commits intopython:mainfrom
Conversation
|
This PR is stale because it has been open for 30 days with no activity. |
JelleZijlstra
left a comment
There was a problem hiding this comment.
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: xCompare 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