@@ -1528,17 +1528,17 @@ class property(object):
1528
1528
if inst is None:
1529
1529
return self
1530
1530
if self.__get is None:
1531
- raise AttributeError, "property has no getter"
1531
+ raise AttributeError( "property has no getter")
1532
1532
return self.__get(inst)
1533
1533
1534
1534
def __set__(self, inst, value):
1535
1535
if self.__set is None:
1536
- raise AttributeError, "property has no setter"
1536
+ raise AttributeError( "property has no setter")
1537
1537
return self.__set(inst, value)
1538
1538
1539
1539
def __delete__(self, inst):
1540
1540
if self.__del is None:
1541
- raise AttributeError, "property has no deleter"
1541
+ raise AttributeError( "property has no deleter")
1542
1542
return self.__del(inst)
1543
1543
1544
1544
*/
@@ -1551,7 +1551,6 @@ static PyMemberDef property_members[] = {
1551
1551
{"fset" , _Py_T_OBJECT , offsetof(propertyobject , prop_set ), Py_READONLY },
1552
1552
{"fdel" , _Py_T_OBJECT , offsetof(propertyobject , prop_del ), Py_READONLY },
1553
1553
{"__doc__" , _Py_T_OBJECT , offsetof(propertyobject , prop_doc ), 0 },
1554
- {"__name__" , _Py_T_OBJECT , offsetof(propertyobject , prop_name ), 0 },
1555
1554
{0 }
1556
1555
};
1557
1556
@@ -1633,6 +1632,20 @@ property_dealloc(PyObject *self)
1633
1632
Py_TYPE (self )-> tp_free (self );
1634
1633
}
1635
1634
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
+
1636
1649
static PyObject *
1637
1650
property_descr_get (PyObject * self , PyObject * obj , PyObject * type )
1638
1651
{
@@ -1642,11 +1655,15 @@ property_descr_get(PyObject *self, PyObject *obj, PyObject *type)
1642
1655
1643
1656
propertyobject * gs = (propertyobject * )self ;
1644
1657
if (gs -> prop_get == NULL ) {
1658
+ PyObject * propname ;
1659
+ if (property_name (gs , & propname ) < 0 ) {
1660
+ return NULL ;
1661
+ }
1645
1662
PyObject * qualname = PyType_GetQualName (Py_TYPE (obj ));
1646
- if (gs -> prop_name != NULL && qualname != NULL ) {
1663
+ if (propname != NULL && qualname != NULL ) {
1647
1664
PyErr_Format (PyExc_AttributeError ,
1648
1665
"property %R of %R object has no getter" ,
1649
- gs -> prop_name ,
1666
+ propname ,
1650
1667
qualname );
1651
1668
}
1652
1669
else if (qualname != NULL ) {
@@ -1657,6 +1674,7 @@ property_descr_get(PyObject *self, PyObject *obj, PyObject *type)
1657
1674
PyErr_SetString (PyExc_AttributeError ,
1658
1675
"property has no getter" );
1659
1676
}
1677
+ Py_XDECREF (propname );
1660
1678
Py_XDECREF (qualname );
1661
1679
return NULL ;
1662
1680
}
@@ -1678,16 +1696,20 @@ property_descr_set(PyObject *self, PyObject *obj, PyObject *value)
1678
1696
}
1679
1697
1680
1698
if (func == NULL ) {
1699
+ PyObject * propname ;
1700
+ if (property_name (gs , & propname ) < 0 ) {
1701
+ return -1 ;
1702
+ }
1681
1703
PyObject * qualname = NULL ;
1682
1704
if (obj != NULL ) {
1683
1705
qualname = PyType_GetQualName (Py_TYPE (obj ));
1684
1706
}
1685
- if (gs -> prop_name != NULL && qualname != NULL ) {
1707
+ if (propname != NULL && qualname != NULL ) {
1686
1708
PyErr_Format (PyExc_AttributeError ,
1687
1709
value == NULL ?
1688
1710
"property %R of %R object has no deleter" :
1689
1711
"property %R of %R object has no setter" ,
1690
- gs -> prop_name ,
1712
+ propname ,
1691
1713
qualname );
1692
1714
}
1693
1715
else if (qualname != NULL ) {
@@ -1703,6 +1725,7 @@ property_descr_set(PyObject *self, PyObject *obj, PyObject *value)
1703
1725
"property has no deleter" :
1704
1726
"property has no setter" );
1705
1727
}
1728
+ Py_XDECREF (propname );
1706
1729
Py_XDECREF (qualname );
1707
1730
return -1 ;
1708
1731
}
@@ -1888,6 +1911,28 @@ property_init_impl(propertyobject *self, PyObject *fget, PyObject *fset,
1888
1911
return 0 ;
1889
1912
}
1890
1913
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
+
1891
1936
static PyObject *
1892
1937
property_get___isabstractmethod__ (propertyobject * prop , void * closure )
1893
1938
{
@@ -1918,6 +1963,7 @@ property_get___isabstractmethod__(propertyobject *prop, void *closure)
1918
1963
}
1919
1964
1920
1965
static PyGetSetDef property_getsetlist [] = {
1966
+ {"__name__" , (getter )property_get__name__ , (setter )property_set__name__ },
1921
1967
{"__isabstractmethod__" ,
1922
1968
(getter )property_get___isabstractmethod__ , NULL ,
1923
1969
NULL ,
0 commit comments