@@ -1528,17 +1528,17 @@ class property(object):
15281528 if inst is None:
15291529 return self
15301530 if self.__get is None:
1531- raise AttributeError, "property has no getter"
1531+ raise AttributeError( "property has no getter")
15321532 return self.__get(inst)
15331533
15341534 def __set__(self, inst, value):
15351535 if self.__set is None:
1536- raise AttributeError, "property has no setter"
1536+ raise AttributeError( "property has no setter")
15371537 return self.__set(inst, value)
15381538
15391539 def __delete__(self, inst):
15401540 if self.__del is None:
1541- raise AttributeError, "property has no deleter"
1541+ raise AttributeError( "property has no deleter")
15421542 return self.__del(inst)
15431543
15441544*/
@@ -1551,7 +1551,6 @@ static PyMemberDef property_members[] = {
15511551 {"fset" , _Py_T_OBJECT , offsetof(propertyobject , prop_set ), Py_READONLY },
15521552 {"fdel" , _Py_T_OBJECT , offsetof(propertyobject , prop_del ), Py_READONLY },
15531553 {"__doc__" , _Py_T_OBJECT , offsetof(propertyobject , prop_doc ), 0 },
1554- {"__name__" , _Py_T_OBJECT , offsetof(propertyobject , prop_name ), 0 },
15551554 {0 }
15561555};
15571556
@@ -1633,6 +1632,20 @@ property_dealloc(PyObject *self)
16331632 Py_TYPE (self )-> tp_free (self );
16341633}
16351634
1635+ static int
1636+ property_name (propertyobject * prop , PyObject * * name )
1637+ {
1638+ if (prop -> prop_name != NULL ) {
1639+ * name = Py_NewRef (prop -> prop_name );
1640+ return 1 ;
1641+ }
1642+ if (prop -> prop_get == NULL ) {
1643+ * name = NULL ;
1644+ return 0 ;
1645+ }
1646+ return PyObject_GetOptionalAttr (prop -> prop_get , & _Py_ID (__name__ ), name );
1647+ }
1648+
16361649static PyObject *
16371650property_descr_get (PyObject * self , PyObject * obj , PyObject * type )
16381651{
@@ -1642,11 +1655,15 @@ property_descr_get(PyObject *self, PyObject *obj, PyObject *type)
16421655
16431656 propertyobject * gs = (propertyobject * )self ;
16441657 if (gs -> prop_get == NULL ) {
1658+ PyObject * propname ;
1659+ if (property_name (gs , & propname ) < 0 ) {
1660+ return NULL ;
1661+ }
16451662 PyObject * qualname = PyType_GetQualName (Py_TYPE (obj ));
1646- if (gs -> prop_name != NULL && qualname != NULL ) {
1663+ if (propname != NULL && qualname != NULL ) {
16471664 PyErr_Format (PyExc_AttributeError ,
16481665 "property %R of %R object has no getter" ,
1649- gs -> prop_name ,
1666+ propname ,
16501667 qualname );
16511668 }
16521669 else if (qualname != NULL ) {
@@ -1657,6 +1674,7 @@ property_descr_get(PyObject *self, PyObject *obj, PyObject *type)
16571674 PyErr_SetString (PyExc_AttributeError ,
16581675 "property has no getter" );
16591676 }
1677+ Py_XDECREF (propname );
16601678 Py_XDECREF (qualname );
16611679 return NULL ;
16621680 }
@@ -1678,16 +1696,20 @@ property_descr_set(PyObject *self, PyObject *obj, PyObject *value)
16781696 }
16791697
16801698 if (func == NULL ) {
1699+ PyObject * propname ;
1700+ if (property_name (gs , & propname ) < 0 ) {
1701+ return -1 ;
1702+ }
16811703 PyObject * qualname = NULL ;
16821704 if (obj != NULL ) {
16831705 qualname = PyType_GetQualName (Py_TYPE (obj ));
16841706 }
1685- if (gs -> prop_name != NULL && qualname != NULL ) {
1707+ if (propname != NULL && qualname != NULL ) {
16861708 PyErr_Format (PyExc_AttributeError ,
16871709 value == NULL ?
16881710 "property %R of %R object has no deleter" :
16891711 "property %R of %R object has no setter" ,
1690- gs -> prop_name ,
1712+ propname ,
16911713 qualname );
16921714 }
16931715 else if (qualname != NULL ) {
@@ -1703,6 +1725,7 @@ property_descr_set(PyObject *self, PyObject *obj, PyObject *value)
17031725 "property has no deleter" :
17041726 "property has no setter" );
17051727 }
1728+ Py_XDECREF (propname );
17061729 Py_XDECREF (qualname );
17071730 return -1 ;
17081731 }
@@ -1888,6 +1911,28 @@ property_init_impl(propertyobject *self, PyObject *fget, PyObject *fset,
18881911 return 0 ;
18891912}
18901913
1914+ static PyObject *
1915+ property_get__name__ (propertyobject * prop , void * Py_UNUSED (ignored ))
1916+ {
1917+ PyObject * name ;
1918+ if (property_name (prop , & name ) < 0 ) {
1919+ return NULL ;
1920+ }
1921+ if (name == NULL ) {
1922+ PyErr_SetString (PyExc_AttributeError ,
1923+ "'property' object has no attribute '__name__'" );
1924+ }
1925+ return name ;
1926+ }
1927+
1928+ static int
1929+ property_set__name__ (propertyobject * prop , PyObject * value ,
1930+ void * Py_UNUSED (ignored ))
1931+ {
1932+ Py_XSETREF (prop -> prop_name , Py_XNewRef (value ));
1933+ return 0 ;
1934+ }
1935+
18911936static PyObject *
18921937property_get___isabstractmethod__ (propertyobject * prop , void * closure )
18931938{
@@ -1918,6 +1963,7 @@ property_get___isabstractmethod__(propertyobject *prop, void *closure)
19181963}
19191964
19201965static PyGetSetDef property_getsetlist [] = {
1966+ {"__name__" , (getter )property_get__name__ , (setter )property_set__name__ },
19211967 {"__isabstractmethod__" ,
19221968 (getter )property_get___isabstractmethod__ , NULL ,
19231969 NULL ,
0 commit comments