Skip to content
Merged
Prev Previous commit
Next Next commit
bpo-46730: Make AttributeError show self.__qualname__ instead of owne…
…r type
  • Loading branch information
Alexander Lakeev committed Feb 14, 2022
commit e86f544de62e18e95d18fb95f146131ecbee95c0
4 changes: 2 additions & 2 deletions Lib/test/test_property.py
Original file line number Diff line number Diff line change
Expand Up @@ -335,14 +335,14 @@ def test_del_property(self):


class PropertyUnreachableAttributeWithName(_PropertyUnreachableAttribute, unittest.TestCase):
msg_format = "^property 'foo' originating from 'cls' {}$"
msg_format = "^property 'foo' in object of type 'PropertyUnreachableAttributeWithName.cls' {}$"
Comment thread
Alex-Blade marked this conversation as resolved.
Outdated

class cls:
foo = property()


class PropertyUnreachableAttributeNoName(_PropertyUnreachableAttribute, unittest.TestCase):
msg_format = "^property {}$"
msg_format = "^property in object of type 'PropertyUnreachableAttributeNoName.cls' {}$"
Comment thread
Alex-Blade marked this conversation as resolved.
Outdated

class cls:
pass
Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_sys.py
Original file line number Diff line number Diff line change
Expand Up @@ -1450,7 +1450,7 @@ def getx(self): return self.__x
def setx(self, value): self.__x = value
def delx(self): del self.__x
x = property(getx, setx, delx, "")
check(x, size('6Pi'))
check(x, size('5Pi'))
# PyCapsule
# XXX
# rangeiterator
Expand Down
49 changes: 19 additions & 30 deletions Objects/descrobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -1485,7 +1485,6 @@ typedef struct {
PyObject *prop_del;
PyObject *prop_doc;
PyObject *prop_name;
PyObject *owner_name;
int getter_doc;
} propertyobject;

Expand Down Expand Up @@ -1545,15 +1544,11 @@ property_set_name(PyObject *self, PyObject *args) {
}

propertyobject *prop = (propertyobject *)self;
PyObject *owner_name = PyObject_GetAttrString(PyTuple_GET_ITEM(args, 0), "__name__");
PyObject *name = PyTuple_GET_ITEM(args, 1);

Py_XINCREF(name);
Py_XSETREF(prop->prop_name, name);

Py_XINCREF(owner_name);
Py_XSETREF(prop->owner_name, owner_name);

Py_RETURN_NONE;
}

Expand All @@ -1577,7 +1572,6 @@ property_dealloc(PyObject *self)
Py_XDECREF(gs->prop_del);
Py_XDECREF(gs->prop_doc);
Py_XDECREF(gs->prop_name);
Py_XDECREF(gs->owner_name);
Py_TYPE(self)->tp_free(self);
}

Expand All @@ -1591,15 +1585,15 @@ property_descr_get(PyObject *self, PyObject *obj, PyObject *type)

propertyobject *gs = (propertyobject *)self;
if (gs->prop_get == NULL) {
if (gs->prop_name != NULL && gs->owner_name != NULL) {
if (gs->prop_name != NULL) {
PyErr_Format(PyExc_AttributeError,
"property %R originating from %R has no getter",
"property %R in object of type %R has no getter",
Comment thread
Alex-Blade marked this conversation as resolved.
Outdated
gs->prop_name,
gs->owner_name);
} else if (gs->prop_name != NULL) {
PyErr_Format(PyExc_AttributeError, "property %R has no getter", gs->prop_name);
PyType_GetQualName(Py_TYPE(obj)));
} else {
PyErr_SetString(PyExc_AttributeError, "property has no getter");
PyErr_Format(PyExc_AttributeError,
"property in object of type %R has no getter",
PyType_GetQualName(Py_TYPE(obj)));
}

return NULL;
Expand All @@ -1622,26 +1616,24 @@ property_descr_set(PyObject *self, PyObject *obj, PyObject *value)
}

if (func == NULL) {
if (gs->prop_name != NULL && gs->owner_name != NULL) {
if (gs->prop_name != NULL && obj != NULL) {
PyErr_Format(PyExc_AttributeError,
value == NULL ?
"property %R originating from %R has no deleter" :
"property %R originating from %R has no setter",
"property %R in object of type %R has no deleter" :
"property %R in object of type %R has no setter",
gs->prop_name,
gs->owner_name);
}
else if (gs->prop_name != NULL) {
PyType_GetQualName(Py_TYPE(obj)));
} else if (obj != NULL) {
Comment thread
Alex-Blade marked this conversation as resolved.
Outdated
PyErr_Format(PyExc_AttributeError,
value == NULL ?
"property %R has no deleter" :
"property %R has no setter",
gs->prop_name);
}
else {
PyErr_SetString(PyExc_AttributeError,
value == NULL ?
"property has no deleter" :
"property has no setter");
"property in object of type %R has no deleter" :
"property in object of type %R has no setter",
PyType_GetQualName(Py_TYPE(obj)));
} else {
PyErr_SetString(PyExc_AttributeError,
value == NULL ?
"property has no deleter" :
"property has no setter");
}
return -1;
}
Expand Down Expand Up @@ -1699,9 +1691,6 @@ property_copy(PyObject *old, PyObject *get, PyObject *set, PyObject *del)

Py_XINCREF(pold->prop_name);
Py_XSETREF(((propertyobject *) new)->prop_name, pold->prop_name);

Py_XINCREF(pold->owner_name);
Py_XSETREF(((propertyobject *) new)->owner_name, pold->owner_name);
return new;
}

Expand Down