summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkj <28750310+Fidget-Spinner@users.noreply.github.com>2020-11-16 03:27:23 (GMT)
committerGitHub <noreply@github.com>2020-11-16 03:27:23 (GMT)
commit384b7a4bd988986bca227c7e85c32d766da74708 (patch)
treedbcb20fceb8d8e1f7e619b4007722b928c29c389
parentc272d40e5b7180861d4a97589855142d15e9ddf2 (diff)
downloadcpython-384b7a4bd988986bca227c7e85c32d766da74708.zip
cpython-384b7a4bd988986bca227c7e85c32d766da74708.tar.gz
cpython-384b7a4bd988986bca227c7e85c32d766da74708.tar.bz2
bpo-42332: Add weakref slot to types.GenericAlias (GH-23250)
Automerge-Triggered-By: GH:gvanrossum
-rw-r--r--Lib/test/test_genericalias.py86
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2020-11-12-23-16-14.bpo-42332.fEQIdk.rst1
-rw-r--r--Objects/genericaliasobject.c6
3 files changed, 55 insertions, 38 deletions
diff --git a/Lib/test/test_genericalias.py b/Lib/test/test_genericalias.py
index 2979cfb..912fb33 100644
--- a/Lib/test/test_genericalias.py
+++ b/Lib/test/test_genericalias.py
@@ -47,46 +47,46 @@ V = TypeVar('V')
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 @@ class BaseTest(unittest.TestCase):
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 0000000..8a2cb87
--- /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 28ea487..6102e05 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;
}