From 8a964ab089182b372e0d5f9c722f001399792b03 Mon Sep 17 00:00:00 2001 From: Yurii Karabas <1998uriyyo@gmail.com> Date: Mon, 13 Sep 2021 11:16:56 +0300 Subject: [PATCH 1/2] bpo-45167: Add ability to deepcopy types.GenericAlias --- Lib/copy.py | 4 ++++ Lib/test/test_copy.py | 6 ++++++ .../2021-09-13-11-15-33.bpo-45167.lupMrM.rst | 2 ++ 3 files changed, 12 insertions(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2021-09-13-11-15-33.bpo-45167.lupMrM.rst diff --git a/Lib/copy.py b/Lib/copy.py index dd41c54dffe1d71..8ab9d79891eacbb 100644 --- a/Lib/copy.py +++ b/Lib/copy.py @@ -238,6 +238,10 @@ def _deepcopy_method(x, memo): # Copy instance methods return type(x)(x.__func__, deepcopy(x.__self__, memo)) d[types.MethodType] = _deepcopy_method +def _deepcopy_genericalias(x, memo): + return type(x)(deepcopy(x.__origin__, memo), deepcopy(x.__args__, memo)) +d[types.GenericAlias] = _deepcopy_genericalias + del d def _keep_alive(x, memo): diff --git a/Lib/test/test_copy.py b/Lib/test/test_copy.py index f1ca8cb254d1887..344a964e732adbb 100644 --- a/Lib/test/test_copy.py +++ b/Lib/test/test_copy.py @@ -874,6 +874,12 @@ def m(self): self.assertIs(g.b.__self__, g) g.b() + def test_deepcopy_generic_alias(self): + x = list[int] + g = copy.deepcopy(x) + + self.assertEqual(x, g) + def global_foo(x, y): return x+y diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-09-13-11-15-33.bpo-45167.lupMrM.rst b/Misc/NEWS.d/next/Core and Builtins/2021-09-13-11-15-33.bpo-45167.lupMrM.rst new file mode 100644 index 000000000000000..6aff3a34630dd53 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2021-09-13-11-15-33.bpo-45167.lupMrM.rst @@ -0,0 +1,2 @@ +Add ability to deepcopy ``types.GenericAlias``. Patch provided by Yurii +Karabas. From c59c7e980b5691b227c9c66e4e0ca6577a6e65f9 Mon Sep 17 00:00:00 2001 From: Yurii Karabas <1998uriyyo@gmail.com> Date: Tue, 14 Sep 2021 15:25:23 +0300 Subject: [PATCH 2/2] Add __deepcopy__, __copy__ to GenericAlias blacklist --- Lib/copy.py | 4 ---- Objects/genericaliasobject.c | 2 ++ 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Lib/copy.py b/Lib/copy.py index 8ab9d79891eacbb..dd41c54dffe1d71 100644 --- a/Lib/copy.py +++ b/Lib/copy.py @@ -238,10 +238,6 @@ def _deepcopy_method(x, memo): # Copy instance methods return type(x)(x.__func__, deepcopy(x.__self__, memo)) d[types.MethodType] = _deepcopy_method -def _deepcopy_genericalias(x, memo): - return type(x)(deepcopy(x.__origin__, memo), deepcopy(x.__args__, memo)) -d[types.GenericAlias] = _deepcopy_genericalias - del d def _keep_alive(x, memo): diff --git a/Objects/genericaliasobject.c b/Objects/genericaliasobject.c index 38b68e410c443c3..dbe5d89b7396296 100644 --- a/Objects/genericaliasobject.c +++ b/Objects/genericaliasobject.c @@ -418,6 +418,8 @@ static const char* const attr_exceptions[] = { "__mro_entries__", "__reduce_ex__", // needed so we don't look up object.__reduce_ex__ "__reduce__", + "__copy__", + "__deepcopy__", NULL, };