]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-106403: Restore weakref support for TypeVar and friends (#106418)
authorJelle Zijlstra <jelle.zijlstra@gmail.com>
Tue, 11 Jul 2023 15:43:24 +0000 (08:43 -0700)
committerGitHub <noreply@github.com>
Tue, 11 Jul 2023 15:43:24 +0000 (08:43 -0700)
Lib/test/test_type_params.py
Misc/NEWS.d/next/Library/2023-07-04-07-25-30.gh-issue-106403.GmefbV.rst [new file with mode: 0644]
Objects/typevarobject.c

index 3026cc224766198806d976f1abfa08b3db91f06e..bced641a9661fd7b1a509cfe5e11a34e328b795b 100644 (file)
@@ -3,6 +3,7 @@ import textwrap
 import types
 import unittest
 import pickle
+import weakref
 from test.support import requires_working_socket, check_syntax_error, run_code
 
 from typing import Generic, Sequence, TypeVar, TypeVarTuple, ParamSpec, get_args
@@ -921,3 +922,33 @@ class TypeParamsPickleTest(unittest.TestCase):
                     # These instances are not equal,
                     # but class check is good enough:
                     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)
diff --git a/Misc/NEWS.d/next/Library/2023-07-04-07-25-30.gh-issue-106403.GmefbV.rst b/Misc/NEWS.d/next/Library/2023-07-04-07-25-30.gh-issue-106403.GmefbV.rst
new file mode 100644 (file)
index 0000000..4fea45f
--- /dev/null
@@ -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.
index 0b44f84b6f01d2fd6d2a8380e5ad2b84b46cfa14..5605662f0e6d5e63999a8dd6697236b9670b7556 100644 (file)
@@ -500,7 +500,7 @@ PyType_Spec typevar_spec = {
     .name = "typing.TypeVar",
     .basicsize = sizeof(typevarobject),
     .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,
 };
 
@@ -647,7 +647,8 @@ static PyType_Slot paramspecargs_slots[] = {
 PyType_Spec paramspecargs_spec = {
     .name = "typing.ParamSpecArgs",
     .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,
 };
 
@@ -726,7 +727,8 @@ static PyType_Slot paramspeckwargs_slots[] = {
 PyType_Spec paramspeckwargs_spec = {
     .name = "typing.ParamSpecKwargs",
     .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,
 };
 
@@ -1007,7 +1009,7 @@ PyType_Spec paramspec_spec = {
     .name = "typing.ParamSpec",
     .basicsize = sizeof(paramspecobject),
     .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,
 };
 
@@ -1228,7 +1230,7 @@ PyType_Spec typevartuple_spec = {
     .name = "typing.TypeVarTuple",
     .basicsize = sizeof(typevartupleobject),
     .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,
 };