gh-106403: Restore weakref support for TypeVar and friends (#106418)

This commit is contained in:
Jelle Zijlstra 2023-07-11 08:43:24 -07:00 committed by GitHub
parent a2d54d4e8a
commit 945d3cbf2e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 5 deletions

View File

@ -3,6 +3,7 @@ import textwrap
import types import types
import unittest import unittest
import pickle import pickle
import weakref
from test.support import requires_working_socket, check_syntax_error, run_code from test.support import requires_working_socket, check_syntax_error, run_code
from typing import Generic, Sequence, TypeVar, TypeVarTuple, ParamSpec, get_args from typing import Generic, Sequence, TypeVar, TypeVarTuple, ParamSpec, get_args
@ -921,3 +922,33 @@ class TypeParamsPickleTest(unittest.TestCase):
# These instances are not equal, # These instances are not equal,
# but class check is good enough: # but class check is good enough:
self.assertIsInstance(pickle.loads(pickled), real_class) self.assertIsInstance(pickle.loads(pickled), real_class)
class TypeParamsWeakRefTest(unittest.TestCase):
def test_weakrefs(self):
T = TypeVar('T')
P = ParamSpec('P')
class OldStyle(Generic[T]):
pass
class NewStyle[T]:
pass
cases = [
T,
TypeVar('T', bound=int),
P,
P.args,
P.kwargs,
TypeVarTuple('Ts'),
OldStyle,
OldStyle[int],
OldStyle(),
NewStyle,
NewStyle[int],
NewStyle(),
Generic[T],
]
for case in cases:
with self.subTest(case=case):
weakref.ref(case)

View File

@ -0,0 +1,4 @@
Instances of :class:`typing.TypeVar`, :class:`typing.ParamSpec`,
:class:`typing.ParamSpecArgs`, :class:`typing.ParamSpecKwargs`, and
:class:`typing.TypeVarTuple` once again support weak references, fixing a
regression introduced in Python 3.12.0 beta 1. Patch by Jelle Zijlstra.

View File

@ -500,7 +500,7 @@ PyType_Spec typevar_spec = {
.name = "typing.TypeVar", .name = "typing.TypeVar",
.basicsize = sizeof(typevarobject), .basicsize = sizeof(typevarobject),
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE
| Py_TPFLAGS_MANAGED_DICT, | Py_TPFLAGS_MANAGED_DICT | Py_TPFLAGS_MANAGED_WEAKREF,
.slots = typevar_slots, .slots = typevar_slots,
}; };
@ -647,7 +647,8 @@ static PyType_Slot paramspecargs_slots[] = {
PyType_Spec paramspecargs_spec = { PyType_Spec paramspecargs_spec = {
.name = "typing.ParamSpecArgs", .name = "typing.ParamSpecArgs",
.basicsize = sizeof(paramspecattrobject), .basicsize = sizeof(paramspecattrobject),
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE, .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE
| Py_TPFLAGS_MANAGED_WEAKREF,
.slots = paramspecargs_slots, .slots = paramspecargs_slots,
}; };
@ -726,7 +727,8 @@ static PyType_Slot paramspeckwargs_slots[] = {
PyType_Spec paramspeckwargs_spec = { PyType_Spec paramspeckwargs_spec = {
.name = "typing.ParamSpecKwargs", .name = "typing.ParamSpecKwargs",
.basicsize = sizeof(paramspecattrobject), .basicsize = sizeof(paramspecattrobject),
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE, .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE
| Py_TPFLAGS_MANAGED_WEAKREF,
.slots = paramspeckwargs_slots, .slots = paramspeckwargs_slots,
}; };
@ -1007,7 +1009,7 @@ PyType_Spec paramspec_spec = {
.name = "typing.ParamSpec", .name = "typing.ParamSpec",
.basicsize = sizeof(paramspecobject), .basicsize = sizeof(paramspecobject),
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE
| Py_TPFLAGS_MANAGED_DICT, | Py_TPFLAGS_MANAGED_DICT | Py_TPFLAGS_MANAGED_WEAKREF,
.slots = paramspec_slots, .slots = paramspec_slots,
}; };
@ -1228,7 +1230,7 @@ PyType_Spec typevartuple_spec = {
.name = "typing.TypeVarTuple", .name = "typing.TypeVarTuple",
.basicsize = sizeof(typevartupleobject), .basicsize = sizeof(typevartupleobject),
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_MANAGED_DICT .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_MANAGED_DICT
| Py_TPFLAGS_HAVE_GC, | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_MANAGED_WEAKREF,
.slots = typevartuple_slots, .slots = typevartuple_slots,
}; };