Skip to content

Commit

Permalink
pythongh-106403: Restore weakref support for TypeVar and friends
Browse files Browse the repository at this point in the history
  • Loading branch information
JelleZijlstra committed Jul 4, 2023
1 parent dfe4de2 commit df59646
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 5 deletions.
31 changes: 31 additions & 0 deletions Lib/test/test_type_params.py
Expand Up @@ -3,6 +3,7 @@
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
Expand Down Expand Up @@ -921,3 +922,33 @@ def test_pickling_classes(self):
# 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)
@@ -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.
12 changes: 7 additions & 5 deletions Objects/typevarobject.c
Expand Up @@ -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,
};

Expand Down Expand Up @@ -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,
};

Expand Down Expand Up @@ -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,
};

Expand Down Expand Up @@ -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,
};

Expand Down Expand Up @@ -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,
};

Expand Down

0 comments on commit df59646

Please sign in to comment.