@@ -1519,22 +1519,34 @@ class property(object):
15191519 self.__doc__ = doc
15201520 except AttributeError: # read-only or dict-less class
15211521 pass
1522+ self.__name = None
1523+
1524+ def __set_name__(self, owner, 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
15221534
15231535 def __get__(self, inst, type=None):
15241536 if inst is None:
15251537 return self
15261538 if self.__get is None:
1527- raise AttributeError, "property has no getter"
1539+ raise AttributeError( "property has no getter")
15281540 return self.__get(inst)
15291541
15301542 def __set__(self, inst, value):
15311543 if self.__set is None:
1532- raise AttributeError, "property has no setter"
1544+ raise AttributeError( "property has no setter")
15331545 return self.__set(inst, value)
15341546
15351547 def __delete__(self, inst):
15361548 if self.__del is None:
1537- raise AttributeError, "property has no deleter"
1549+ raise AttributeError( "property has no deleter")
15381550 return self.__del(inst)
15391551
15401552*/
@@ -1628,6 +1640,20 @@ property_dealloc(PyObject *self)
16281640 Py_TYPE (self )-> tp_free (self );
16291641}
16301642
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+
16311657static PyObject *
16321658property_descr_get (PyObject * self , PyObject * obj , PyObject * type )
16331659{
@@ -1637,11 +1663,15 @@ property_descr_get(PyObject *self, PyObject *obj, PyObject *type)
16371663
16381664 propertyobject * gs = (propertyobject * )self ;
16391665 if (gs -> prop_get == NULL ) {
1666+ PyObject * propname ;
1667+ if (property_name (gs , & propname ) < 0 ) {
1668+ return NULL ;
1669+ }
16401670 PyObject * qualname = PyType_GetQualName (Py_TYPE (obj ));
1641- if (gs -> prop_name != NULL && qualname != NULL ) {
1671+ if (propname != NULL && qualname != NULL ) {
16421672 PyErr_Format (PyExc_AttributeError ,
16431673 "property %R of %R object has no getter" ,
1644- gs -> prop_name ,
1674+ propname ,
16451675 qualname );
16461676 }
16471677 else if (qualname != NULL ) {
@@ -1652,6 +1682,7 @@ property_descr_get(PyObject *self, PyObject *obj, PyObject *type)
16521682 PyErr_SetString (PyExc_AttributeError ,
16531683 "property has no getter" );
16541684 }
1685+ Py_XDECREF (propname );
16551686 Py_XDECREF (qualname );
16561687 return NULL ;
16571688 }
@@ -1673,16 +1704,20 @@ property_descr_set(PyObject *self, PyObject *obj, PyObject *value)
16731704 }
16741705
16751706 if (func == NULL ) {
1707+ PyObject * propname ;
1708+ if (property_name (gs , & propname ) < 0 ) {
1709+ return -1 ;
1710+ }
16761711 PyObject * qualname = NULL ;
16771712 if (obj != NULL ) {
16781713 qualname = PyType_GetQualName (Py_TYPE (obj ));
16791714 }
1680- if (gs -> prop_name != NULL && qualname != NULL ) {
1715+ if (propname != NULL && qualname != NULL ) {
16811716 PyErr_Format (PyExc_AttributeError ,
16821717 value == NULL ?
16831718 "property %R of %R object has no deleter" :
16841719 "property %R of %R object has no setter" ,
1685- gs -> prop_name ,
1720+ propname ,
16861721 qualname );
16871722 }
16881723 else if (qualname != NULL ) {
@@ -1698,6 +1733,7 @@ property_descr_set(PyObject *self, PyObject *obj, PyObject *value)
16981733 "property has no deleter" :
16991734 "property has no setter" );
17001735 }
1736+ Py_XDECREF (propname );
17011737 Py_XDECREF (qualname );
17021738 return -1 ;
17031739 }
@@ -1883,6 +1919,28 @@ property_init_impl(propertyobject *self, PyObject *fget, PyObject *fset,
18831919 return 0 ;
18841920}
18851921
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+
18861944static PyObject *
18871945property_get___isabstractmethod__ (propertyobject * prop , void * closure )
18881946{
@@ -1913,6 +1971,7 @@ property_get___isabstractmethod__(propertyobject *prop, void *closure)
19131971}
19141972
19151973static PyGetSetDef property_getsetlist [] = {
1974+ {"__name__" , (getter )property_get__name__ , (setter )property_set__name__ },
19161975 {"__isabstractmethod__" ,
19171976 (getter )property_get___isabstractmethod__ , NULL ,
19181977 NULL ,
0 commit comments