[Python-checkins] bpo-42332: Add weakref slot to types.GenericAlias (GH-23250)

miss-islington webhook-mailer at python.org
Sun Nov 15 22:27:37 EST 2020


https://github.com/python/cpython/commit/384b7a4bd988986bca227c7e85c32d766da74708
commit: 384b7a4bd988986bca227c7e85c32d766da74708
branch: master
author: kj <28750310+Fidget-Spinner at users.noreply.github.com>
committer: miss-islington <31488909+miss-islington at users.noreply.github.com>
date: 2020-11-15T19:27:23-08:00
summary:

bpo-42332: Add weakref slot to types.GenericAlias (GH-23250)



Automerge-Triggered-By: GH:gvanrossum

files:
A Misc/NEWS.d/next/Core and Builtins/2020-11-12-23-16-14.bpo-42332.fEQIdk.rst
M Lib/test/test_genericalias.py
M Objects/genericaliasobject.c

diff --git a/Lib/test/test_genericalias.py b/Lib/test/test_genericalias.py
index 2979cfb55083c..912fb33af1a21 100644
--- a/Lib/test/test_genericalias.py
+++ b/Lib/test/test_genericalias.py
@@ -47,46 +47,46 @@
 
 class BaseTest(unittest.TestCase):
     """Test basics."""
+    generic_types = [type, tuple, list, dict, set, frozenset, enumerate,
+                     defaultdict, deque,
+                     SequenceMatcher,
+                     dircmp,
+                     FileInput,
+                     OrderedDict, Counter, UserDict, UserList,
+                     Pattern, Match,
+                     partial, partialmethod, cached_property,
+                     AbstractContextManager, AbstractAsyncContextManager,
+                     Awaitable, Coroutine,
+                     AsyncIterable, AsyncIterator,
+                     AsyncGenerator, Generator,
+                     Iterable, Iterator,
+                     Reversible,
+                     Container, Collection,
+                     Callable,
+                     Mailbox, _PartialFile,
+                     ContextVar, Token,
+                     Field,
+                     Set, MutableSet,
+                     Mapping, MutableMapping, MappingView,
+                     KeysView, ItemsView, ValuesView,
+                     Sequence, MutableSequence,
+                     MappingProxyType, AsyncGeneratorType,
+                     DirEntry,
+                     chain,
+                     TemporaryDirectory, SpooledTemporaryFile,
+                     Queue, SimpleQueue,
+                     _AssertRaisesContext,
+                     SplitResult, ParseResult,
+                     ValueProxy, ApplyResult,
+                     WeakSet, ReferenceType, ref,
+                     ShareableList, MPSimpleQueue,
+                     Future, _WorkItem,
+                     Morsel]
+    if ctypes is not None:
+        generic_types.extend((ctypes.Array, ctypes.LibraryLoader))
 
     def test_subscriptable(self):
-        types = [type, tuple, list, dict, set, frozenset, enumerate,
-                 defaultdict, deque,
-                 SequenceMatcher,
-                 dircmp,
-                 FileInput,
-                 OrderedDict, Counter, UserDict, UserList,
-                 Pattern, Match,
-                 partial, partialmethod, cached_property,
-                 AbstractContextManager, AbstractAsyncContextManager,
-                 Awaitable, Coroutine,
-                 AsyncIterable, AsyncIterator,
-                 AsyncGenerator, Generator,
-                 Iterable, Iterator,
-                 Reversible,
-                 Container, Collection,
-                 Callable,
-                 Mailbox, _PartialFile,
-                 ContextVar, Token,
-                 Field,
-                 Set, MutableSet,
-                 Mapping, MutableMapping, MappingView,
-                 KeysView, ItemsView, ValuesView,
-                 Sequence, MutableSequence,
-                 MappingProxyType, AsyncGeneratorType,
-                 DirEntry,
-                 chain,
-                 TemporaryDirectory, SpooledTemporaryFile,
-                 Queue, SimpleQueue,
-                 _AssertRaisesContext,
-                 SplitResult, ParseResult,
-                 ValueProxy, ApplyResult,
-                 WeakSet, ReferenceType, ref,
-                 ShareableList, MPSimpleQueue,
-                 Future, _WorkItem,
-                 Morsel]
-        if ctypes is not None:
-            types.extend((ctypes.Array, ctypes.LibraryLoader))
-        for t in types:
+        for t in self.generic_types:
             if t is None:
                 continue
             tname = t.__name__
@@ -293,5 +293,15 @@ def test_dir(self):
         for generic_alias_property in ("__origin__", "__args__", "__parameters__"):
             self.assertIn(generic_alias_property, dir_of_gen_alias)
 
+    def test_weakref(self):
+        for t in self.generic_types:
+            if t is None:
+                continue
+            tname = t.__name__
+            with self.subTest(f"Testing {tname}"):
+                alias = t[int]
+                self.assertEqual(ref(alias)(), alias)
+
+
 if __name__ == "__main__":
     unittest.main()
diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-11-12-23-16-14.bpo-42332.fEQIdk.rst b/Misc/NEWS.d/next/Core and Builtins/2020-11-12-23-16-14.bpo-42332.fEQIdk.rst
new file mode 100644
index 0000000000000..8a2cb87cc0bd2
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2020-11-12-23-16-14.bpo-42332.fEQIdk.rst	
@@ -0,0 +1 @@
+:class:`types.GenericAlias` objects can now be the targets of weakrefs.
diff --git a/Objects/genericaliasobject.c b/Objects/genericaliasobject.c
index 28ea487a44f55..6102e05c165c5 100644
--- a/Objects/genericaliasobject.c
+++ b/Objects/genericaliasobject.c
@@ -10,6 +10,7 @@ typedef struct {
     PyObject *origin;
     PyObject *args;
     PyObject *parameters;
+    PyObject* weakreflist;
 } gaobject;
 
 static void
@@ -18,6 +19,9 @@ ga_dealloc(PyObject *self)
     gaobject *alias = (gaobject *)self;
 
     _PyObject_GC_UNTRACK(self);
+    if (alias->weakreflist != NULL) {
+        PyObject_ClearWeakRefs((PyObject *)alias);
+    }
     Py_XDECREF(alias->origin);
     Py_XDECREF(alias->args);
     Py_XDECREF(alias->parameters);
@@ -599,6 +603,7 @@ PyTypeObject Py_GenericAliasType = {
     .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
     .tp_traverse = ga_traverse,
     .tp_richcompare = ga_richcompare,
+    .tp_weaklistoffset = offsetof(gaobject, weakreflist),
     .tp_methods = ga_methods,
     .tp_members = ga_members,
     .tp_alloc = PyType_GenericAlloc,
@@ -630,6 +635,7 @@ Py_GenericAlias(PyObject *origin, PyObject *args)
     alias->origin = origin;
     alias->args = args;
     alias->parameters = NULL;
+    alias->weakreflist = NULL;
     _PyObject_GC_TRACK(alias);
     return (PyObject *)alias;
 }



More information about the Python-checkins mailing list