mirror of
https://github.com/python/cpython.git
synced 2025-12-10 02:50:09 +00:00
gh-98963: Restore the ability to have a dict-less property. (#105262)
Ignore doc string assignment failures in `property` as has been the behavior of all past Python releases.
This commit is contained in:
parent
1237fb6a4b
commit
418befd75d
3 changed files with 97 additions and 13 deletions
|
|
@ -1485,7 +1485,10 @@ class property(object):
|
|||
self.__get = fget
|
||||
self.__set = fset
|
||||
self.__del = fdel
|
||||
self.__doc__ = doc
|
||||
try:
|
||||
self.__doc__ = doc
|
||||
except AttributeError: # read-only or dict-less class
|
||||
pass
|
||||
|
||||
def __get__(self, inst, type=None):
|
||||
if inst is None:
|
||||
|
|
@ -1791,6 +1794,19 @@ property_init_impl(propertyobject *self, PyObject *fget, PyObject *fset,
|
|||
if (rc <= 0) {
|
||||
return rc;
|
||||
}
|
||||
if (!Py_IS_TYPE(self, &PyProperty_Type) &&
|
||||
prop_doc != NULL && prop_doc != Py_None) {
|
||||
// This oddity preserves the long existing behavior of surfacing
|
||||
// an AttributeError when using a dict-less (__slots__) property
|
||||
// subclass as a decorator on a getter method with a docstring.
|
||||
// See PropertySubclassTest.test_slots_docstring_copy_exception.
|
||||
int err = PyObject_SetAttr(
|
||||
(PyObject *)self, &_Py_ID(__doc__), prop_doc);
|
||||
if (err < 0) {
|
||||
Py_DECREF(prop_doc); // release our new reference.
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (prop_doc == Py_None) {
|
||||
prop_doc = NULL;
|
||||
Py_DECREF(Py_None);
|
||||
|
|
@ -1806,19 +1822,32 @@ property_init_impl(propertyobject *self, PyObject *fget, PyObject *fset,
|
|||
if (Py_IS_TYPE(self, &PyProperty_Type)) {
|
||||
Py_XSETREF(self->prop_doc, prop_doc);
|
||||
} else {
|
||||
/* If this is a property subclass, put __doc__
|
||||
in dict of the subclass instance instead,
|
||||
otherwise it gets shadowed by __doc__ in the
|
||||
class's dict. */
|
||||
/* If this is a property subclass, put __doc__ in the dict
|
||||
or designated slot of the subclass instance instead, otherwise
|
||||
it gets shadowed by __doc__ in the class's dict. */
|
||||
|
||||
if (prop_doc == NULL) {
|
||||
prop_doc = Py_NewRef(Py_None);
|
||||
}
|
||||
int err = PyObject_SetAttr(
|
||||
(PyObject *)self, &_Py_ID(__doc__), prop_doc);
|
||||
Py_XDECREF(prop_doc);
|
||||
if (err < 0)
|
||||
return -1;
|
||||
Py_DECREF(prop_doc);
|
||||
if (err < 0) {
|
||||
assert(PyErr_Occurred());
|
||||
if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
|
||||
PyErr_Clear();
|
||||
// https://github.com/python/cpython/issues/98963#issuecomment-1574413319
|
||||
// Python silently dropped this doc assignment through 3.11.
|
||||
// We preserve that behavior for backwards compatibility.
|
||||
//
|
||||
// If we ever want to deprecate this behavior, only raise a
|
||||
// warning or error when proc_doc is not None so that
|
||||
// property without a specific doc= still works.
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue