Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita95138b

Browse files
bpo-43857: Improve the AttributeError message when deleting a missing attribute (#25424)
Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
1 parent43b135f commita95138b

File tree

4 files changed

+62
-5
lines changed

4 files changed

+62
-5
lines changed

‎Lib/test/test_class.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,49 @@ class A:
611611
withself.assertRaises(TypeError):
612612
type.__setattr__(A,b'x',None)
613613

614+
deftestTypeAttributeAccessErrorMessages(self):
615+
classA:
616+
pass
617+
618+
error_msg="type object 'A' has no attribute 'x'"
619+
withself.assertRaisesRegex(AttributeError,error_msg):
620+
A.x
621+
withself.assertRaisesRegex(AttributeError,error_msg):
622+
delA.x
623+
624+
deftestObjectAttributeAccessErrorMessages(self):
625+
classA:
626+
pass
627+
classB:
628+
y=0
629+
__slots__= ('z',)
630+
631+
error_msg="'A' object has no attribute 'x'"
632+
withself.assertRaisesRegex(AttributeError,error_msg):
633+
A().x
634+
withself.assertRaisesRegex(AttributeError,error_msg):
635+
delA().x
636+
637+
error_msg="'B' object has no attribute 'x'"
638+
withself.assertRaisesRegex(AttributeError,error_msg):
639+
B().x
640+
withself.assertRaisesRegex(AttributeError,error_msg):
641+
delB().x
642+
withself.assertRaisesRegex(AttributeError,error_msg):
643+
B().x=0
644+
645+
error_msg="'B' object attribute 'y' is read-only"
646+
withself.assertRaisesRegex(AttributeError,error_msg):
647+
delB().y
648+
withself.assertRaisesRegex(AttributeError,error_msg):
649+
B().y=0
650+
651+
error_msg='z'
652+
withself.assertRaisesRegex(AttributeError,error_msg):
653+
B().z
654+
withself.assertRaisesRegex(AttributeError,error_msg):
655+
delB().z
656+
614657
deftestConstructorErrorMessages(self):
615658
# bpo-31506: Improves the error message logic for object_new & object_init
616659

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Improve the:exc:`AttributeError` message when deleting a missing attribute.
2+
Patch by Géry Ogam.

‎Objects/dictobject.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5472,7 +5472,9 @@ _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values,
54725472
values->values[ix]=value;
54735473
if (old_value==NULL) {
54745474
if (value==NULL) {
5475-
PyErr_SetObject(PyExc_AttributeError,name);
5475+
PyErr_Format(PyExc_AttributeError,
5476+
"'%.100s' object has no attribute '%U'",
5477+
Py_TYPE(obj)->tp_name,name);
54765478
return-1;
54775479
}
54785480
_PyDictValues_AddToInsertionOrder(values,ix);

‎Objects/object.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1382,7 +1382,7 @@ _PyObject_GenericSetAttrWithDict(PyObject *obj, PyObject *name,
13821382
return-1;
13831383

13841384
Py_INCREF(name);
1385-
1385+
Py_INCREF(tp);
13861386
descr=_PyType_Lookup(tp,name);
13871387

13881388
if (descr!=NULL) {
@@ -1426,11 +1426,21 @@ _PyObject_GenericSetAttrWithDict(PyObject *obj, PyObject *name,
14261426
res=PyDict_SetItem(dict,name,value);
14271427
Py_DECREF(dict);
14281428
}
1429-
if (res<0&&PyErr_ExceptionMatches(PyExc_KeyError))
1430-
PyErr_SetObject(PyExc_AttributeError,name);
1431-
1429+
if (res<0&&PyErr_ExceptionMatches(PyExc_KeyError)) {
1430+
if (PyType_IsSubtype(tp,&PyType_Type)) {
1431+
PyErr_Format(PyExc_AttributeError,
1432+
"type object '%.50s' has no attribute '%U'",
1433+
((PyTypeObject*)obj)->tp_name,name);
1434+
}
1435+
else {
1436+
PyErr_Format(PyExc_AttributeError,
1437+
"'%.100s' object has no attribute '%U'",
1438+
tp->tp_name,name);
1439+
}
1440+
}
14321441
done:
14331442
Py_XDECREF(descr);
1443+
Py_DECREF(tp);
14341444
Py_DECREF(name);
14351445
returnres;
14361446
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp