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:
Jelle Zijlstra 2025-08-12 04:16:54 -07:00 committed by GitHub
parent 027cacb67c
commit 6859b95cff
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 117 additions and 7 deletions

View file

@ -1793,6 +1793,37 @@ sys__baserepl(PyObject *module, PyObject *Py_UNUSED(ignored))
return sys__baserepl_impl(module);
}
PyDoc_STRVAR(sys__clear_type_descriptors__doc__,
"_clear_type_descriptors($module, type, /)\n"
"--\n"
"\n"
"Private function for clearing certain descriptors from a type\'s dictionary.\n"
"\n"
"See gh-135228 for context.");
#define SYS__CLEAR_TYPE_DESCRIPTORS_METHODDEF \
{"_clear_type_descriptors", (PyCFunction)sys__clear_type_descriptors, METH_O, sys__clear_type_descriptors__doc__},
static PyObject *
sys__clear_type_descriptors_impl(PyObject *module, PyObject *type);
static PyObject *
sys__clear_type_descriptors(PyObject *module, PyObject *arg)
{
PyObject *return_value = NULL;
PyObject *type;
if (!PyObject_TypeCheck(arg, &PyType_Type)) {
_PyArg_BadArgument("_clear_type_descriptors", "argument", (&PyType_Type)->tp_name, arg);
goto exit;
}
type = arg;
return_value = sys__clear_type_descriptors_impl(module, type);
exit:
return return_value;
}
PyDoc_STRVAR(sys__is_gil_enabled__doc__,
"_is_gil_enabled($module, /)\n"
"--\n"
@ -1948,4 +1979,4 @@ exit:
#ifndef SYS_GETANDROIDAPILEVEL_METHODDEF
#define SYS_GETANDROIDAPILEVEL_METHODDEF
#endif /* !defined(SYS_GETANDROIDAPILEVEL_METHODDEF) */
/*[clinic end generated code: output=449d16326e69dcf6 input=a9049054013a1b77]*/
/*[clinic end generated code: output=9052f399f40ca32d input=a9049054013a1b77]*/