bpo-44655: Include the name of the type in unset __slots__ attribute errors (GH-27199)

This commit is contained in:
Pablo Galindo Salgado 2021-07-17 00:34:46 +01:00 committed by GitHub
parent 6714dec5e1
commit f783428a23
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 17 additions and 4 deletions

View File

@ -1303,6 +1303,12 @@ order (MRO) for bases """
with self.assertRaises(AttributeError): with self.assertRaises(AttributeError):
del X().a del X().a
# Inherit from object on purpose to check some backwards compatibility paths
class X(object):
__slots__ = "a"
with self.assertRaisesRegex(AttributeError, "'X' object has no attribute 'a'"):
X().a
def test_slots_special(self): def test_slots_special(self):
# Testing __dict__ and __weakref__ in __slots__... # Testing __dict__ and __weakref__ in __slots__...
class D(object): class D(object):

View File

@ -0,0 +1,2 @@
Include the name of the type in unset __slots__ attribute errors. Patch by
Pablo Galindo

View File

@ -5,11 +5,11 @@
#include "structmember.h" // PyMemberDef #include "structmember.h" // PyMemberDef
PyObject * PyObject *
PyMember_GetOne(const char *addr, PyMemberDef *l) PyMember_GetOne(const char *obj_addr, PyMemberDef *l)
{ {
PyObject *v; PyObject *v;
addr += l->offset; const char* addr = obj_addr + l->offset;
switch (l->type) { switch (l->type) {
case T_BOOL: case T_BOOL:
v = PyBool_FromLong(*(char*)addr); v = PyBool_FromLong(*(char*)addr);
@ -69,8 +69,13 @@ PyMember_GetOne(const char *addr, PyMemberDef *l)
break; break;
case T_OBJECT_EX: case T_OBJECT_EX:
v = *(PyObject **)addr; v = *(PyObject **)addr;
if (v == NULL) if (v == NULL) {
PyErr_SetString(PyExc_AttributeError, l->name); PyObject *obj = (PyObject *)obj_addr;
PyTypeObject *tp = Py_TYPE(obj);
PyErr_Format(PyExc_AttributeError,
"'%.200s' object has no attribute '%s'",
tp->tp_name, l->name);
}
Py_XINCREF(v); Py_XINCREF(v);
break; break;
case T_LONGLONG: case T_LONGLONG: