mirror of
https://github.com/python/cpython.git
synced 2025-10-31 21:51:50 +00:00
gh-135228: When @dataclass(slots=True) replaces a dataclass, make the original class collectible (take 2) (GH-137047)
Remove the `__dict__` and `__weakref__` descriptors from the original class when creating a dataclass from it. An interesting hack, but more localized in scope than gh-135230. This may be a breaking change if people intentionally keep the original class around when using `@dataclass(slots=True)`, and then use `__dict__` or `__weakref__` on the original class. Co-authored-by: Alyssa Coghlan <ncoghlan@gmail.com> Co-authored-by: Petr Viktorin <encukou@gmail.com> Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
This commit is contained in:
parent
027cacb67c
commit
6859b95cff
5 changed files with 117 additions and 7 deletions
|
|
@ -2641,6 +2641,47 @@ sys__baserepl_impl(PyObject *module)
|
|||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
sys._clear_type_descriptors
|
||||
|
||||
type: object(subclass_of='&PyType_Type')
|
||||
/
|
||||
|
||||
Private function for clearing certain descriptors from a type's dictionary.
|
||||
|
||||
See gh-135228 for context.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
sys__clear_type_descriptors_impl(PyObject *module, PyObject *type)
|
||||
/*[clinic end generated code: output=5ad17851b762b6d9 input=dc536c97fde07251]*/
|
||||
{
|
||||
PyTypeObject *typeobj = (PyTypeObject *)type;
|
||||
if (_PyType_HasFeature(typeobj, Py_TPFLAGS_IMMUTABLETYPE)) {
|
||||
PyErr_SetString(PyExc_TypeError, "argument is immutable");
|
||||
return NULL;
|
||||
}
|
||||
PyObject *dict = _PyType_GetDict(typeobj);
|
||||
PyObject *dunder_dict = NULL;
|
||||
if (PyDict_Pop(dict, &_Py_ID(__dict__), &dunder_dict) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
PyObject *dunder_weakref = NULL;
|
||||
if (PyDict_Pop(dict, &_Py_ID(__weakref__), &dunder_weakref) < 0) {
|
||||
PyType_Modified(typeobj);
|
||||
Py_XDECREF(dunder_dict);
|
||||
return NULL;
|
||||
}
|
||||
PyType_Modified(typeobj);
|
||||
// We try to hold onto a reference to these until after we call
|
||||
// PyType_Modified(), in case their deallocation triggers somer user code
|
||||
// that tries to do something to the type.
|
||||
Py_XDECREF(dunder_dict);
|
||||
Py_XDECREF(dunder_weakref);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
/*[clinic input]
|
||||
sys._is_gil_enabled -> bool
|
||||
|
||||
|
|
@ -2837,6 +2878,7 @@ static PyMethodDef sys_methods[] = {
|
|||
SYS__STATS_DUMP_METHODDEF
|
||||
#endif
|
||||
SYS__GET_CPU_COUNT_CONFIG_METHODDEF
|
||||
SYS__CLEAR_TYPE_DESCRIPTORS_METHODDEF
|
||||
SYS__IS_GIL_ENABLED_METHODDEF
|
||||
SYS__DUMP_TRACELETS_METHODDEF
|
||||
{NULL, NULL} // sentinel
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue