@@ -1519,26 +1519,34 @@ class property(object):
15191519 self.__doc__ = doc
15201520 except AttributeError: # read-only or dict-less class
15211521 pass
1522- self.__name__ = None
1522+ self.__name = None
15231523
15241524 def __set_name__(self, owner, name):
1525- self.__name__ = name
1525+ self.__name = name
1526+
1527+ @property
1528+ def __name__(self):
1529+ return self.__name if self.__name is not None else self.fget.__name__
1530+
1531+ @__name__.setter
1532+ def __name__(self, value):
1533+ self.__name = value
15261534
15271535 def __get__(self, inst, type=None):
15281536 if inst is None:
15291537 return self
15301538 if self.__get is None:
1531- raise AttributeError, "property has no getter"
1539+ raise AttributeError( "property has no getter")
15321540 return self.__get(inst)
15331541
15341542 def __set__(self, inst, value):
15351543 if self.__set is None:
1536- raise AttributeError, "property has no setter"
1544+ raise AttributeError( "property has no setter")
15371545 return self.__set(inst, value)
15381546
15391547 def __delete__(self, inst):
15401548 if self.__del is None:
1541- raise AttributeError, "property has no deleter"
1549+ raise AttributeError( "property has no deleter")
15421550 return self.__del(inst)
15431551
15441552*/
@@ -1551,7 +1559,6 @@ static PyMemberDef property_members[] = {
15511559 {"fset" , _Py_T_OBJECT , offsetof(propertyobject , prop_set ), Py_READONLY },
15521560 {"fdel" , _Py_T_OBJECT , offsetof(propertyobject , prop_del ), Py_READONLY },
15531561 {"__doc__" , _Py_T_OBJECT , offsetof(propertyobject , prop_doc ), 0 },
1554- {"__name__" , _Py_T_OBJECT , offsetof(propertyobject , prop_name ), 0 },
15551562 {0 }
15561563};
15571564
@@ -1633,6 +1640,20 @@ property_dealloc(PyObject *self)
16331640 Py_TYPE (self )-> tp_free (self );
16341641}
16351642
1643+ static int
1644+ property_name (propertyobject * prop , PyObject * * name )
1645+ {
1646+ if (prop -> prop_name != NULL ) {
1647+ * name = Py_NewRef (prop -> prop_name );
1648+ return 1 ;
1649+ }
1650+ if (prop -> prop_get == NULL ) {
1651+ * name = NULL ;
1652+ return 0 ;
1653+ }
1654+ return PyObject_GetOptionalAttr (prop -> prop_get , & _Py_ID (__name__ ), name );
1655+ }
1656+
16361657static PyObject *
16371658property_descr_get (PyObject * self , PyObject * obj , PyObject * type )
16381659{
@@ -1642,11 +1663,15 @@ property_descr_get(PyObject *self, PyObject *obj, PyObject *type)
16421663
16431664 propertyobject * gs = (propertyobject * )self ;
16441665 if (gs -> prop_get == NULL ) {
1666+ PyObject * propname ;
1667+ if (property_name (gs , & propname ) < 0 ) {
1668+ return NULL ;
1669+ }
16451670 PyObject * qualname = PyType_GetQualName (Py_TYPE (obj ));
1646- if (gs -> prop_name != NULL && qualname != NULL ) {
1671+ if (propname != NULL && qualname != NULL ) {
16471672 PyErr_Format (PyExc_AttributeError ,
16481673 "property %R of %R object has no getter" ,
1649- gs -> prop_name ,
1674+ propname ,
16501675 qualname );
16511676 }
16521677 else if (qualname != NULL ) {
@@ -1657,6 +1682,7 @@ property_descr_get(PyObject *self, PyObject *obj, PyObject *type)
16571682 PyErr_SetString (PyExc_AttributeError ,
16581683 "property has no getter" );
16591684 }
1685+ Py_XDECREF (propname );
16601686 Py_XDECREF (qualname );
16611687 return NULL ;
16621688 }
@@ -1678,16 +1704,20 @@ property_descr_set(PyObject *self, PyObject *obj, PyObject *value)
16781704 }
16791705
16801706 if (func == NULL ) {
1707+ PyObject * propname ;
1708+ if (property_name (gs , & propname ) < 0 ) {
1709+ return -1 ;
1710+ }
16811711 PyObject * qualname = NULL ;
16821712 if (obj != NULL ) {
16831713 qualname = PyType_GetQualName (Py_TYPE (obj ));
16841714 }
1685- if (gs -> prop_name != NULL && qualname != NULL ) {
1715+ if (propname != NULL && qualname != NULL ) {
16861716 PyErr_Format (PyExc_AttributeError ,
16871717 value == NULL ?
16881718 "property %R of %R object has no deleter" :
16891719 "property %R of %R object has no setter" ,
1690- gs -> prop_name ,
1720+ propname ,
16911721 qualname );
16921722 }
16931723 else if (qualname != NULL ) {
@@ -1703,6 +1733,7 @@ property_descr_set(PyObject *self, PyObject *obj, PyObject *value)
17031733 "property has no deleter" :
17041734 "property has no setter" );
17051735 }
1736+ Py_XDECREF (propname );
17061737 Py_XDECREF (qualname );
17071738 return -1 ;
17081739 }
@@ -1888,6 +1919,28 @@ property_init_impl(propertyobject *self, PyObject *fget, PyObject *fset,
18881919 return 0 ;
18891920}
18901921
1922+ static PyObject *
1923+ property_get__name__ (propertyobject * prop , void * Py_UNUSED (ignored ))
1924+ {
1925+ PyObject * name ;
1926+ if (property_name (prop , & name ) < 0 ) {
1927+ return NULL ;
1928+ }
1929+ if (name == NULL ) {
1930+ PyErr_SetString (PyExc_AttributeError ,
1931+ "'property' object has no attribute '__name__'" );
1932+ }
1933+ return name ;
1934+ }
1935+
1936+ static int
1937+ property_set__name__ (propertyobject * prop , PyObject * value ,
1938+ void * Py_UNUSED (ignored ))
1939+ {
1940+ Py_XSETREF (prop -> prop_name , Py_XNewRef (value ));
1941+ return 0 ;
1942+ }
1943+
18911944static PyObject *
18921945property_get___isabstractmethod__ (propertyobject * prop , void * closure )
18931946{
@@ -1918,6 +1971,7 @@ property_get___isabstractmethod__(propertyobject *prop, void *closure)
19181971}
19191972
19201973static PyGetSetDef property_getsetlist [] = {
1974+ {"__name__" , (getter )property_get__name__ , (setter )property_set__name__ },
19211975 {"__isabstractmethod__" ,
19221976 (getter )property_get___isabstractmethod__ , NULL ,
19231977 NULL ,
0 commit comments