From 74b363104ee01964904d99bb88ee43e757aab0fc Mon Sep 17 00:00:00 2001 From: Stephen Morton Date: Tue, 5 Nov 2024 11:31:15 -0800 Subject: [PATCH 01/10] Register contextvars.Context to collections.abc.Mapping --- Lib/contextvars.py | 4 ++++ Lib/test/test_context.py | 5 +++++ .../Library/2024-11-05-11-28-45.gh-issue-126451.XJMtqz.rst | 2 ++ 3 files changed, 11 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2024-11-05-11-28-45.gh-issue-126451.XJMtqz.rst diff --git a/Lib/contextvars.py b/Lib/contextvars.py index d78c80dfe6f99c..34a553b6455c2b 100644 --- a/Lib/contextvars.py +++ b/Lib/contextvars.py @@ -1,4 +1,8 @@ +import collections.abc from _contextvars import Context, ContextVar, Token, copy_context __all__ = ('Context', 'ContextVar', 'Token', 'copy_context') + + +collections.abc.Mapping.register(Context) diff --git a/Lib/test/test_context.py b/Lib/test/test_context.py index b06b9df9f5b0b8..0600209cf1d0c7 100644 --- a/Lib/test/test_context.py +++ b/Lib/test/test_context.py @@ -1,3 +1,4 @@ +import collections.abc import concurrent.futures import contextvars import functools @@ -350,6 +351,10 @@ def ctx2_fun(): ctx1.run(ctx1_fun) + def test_context_isinstance(self): + ctx = contextvars.Context() + self.assertIsInstance(ctx, collections.abc.Mapping) + @isolated_context @threading_helper.requires_working_threading() def test_context_threads_1(self): diff --git a/Misc/NEWS.d/next/Library/2024-11-05-11-28-45.gh-issue-126451.XJMtqz.rst b/Misc/NEWS.d/next/Library/2024-11-05-11-28-45.gh-issue-126451.XJMtqz.rst new file mode 100644 index 00000000000000..0958211ab78aaa --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-11-05-11-28-45.gh-issue-126451.XJMtqz.rst @@ -0,0 +1,2 @@ +Register the :class:`!contextvars.Context` type to +:class:`!collections.abc.Mapping`. From 9c4e3f5e86a00a5c49beeb7c18a958fd4d5f77b1 Mon Sep 17 00:00:00 2001 From: Stephen Morton Date: Tue, 5 Nov 2024 11:45:04 -0800 Subject: [PATCH 02/10] test that all the methods are present --- Lib/test/test_context.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Lib/test/test_context.py b/Lib/test/test_context.py index 0600209cf1d0c7..6af51f7a72da4e 100644 --- a/Lib/test/test_context.py +++ b/Lib/test/test_context.py @@ -355,6 +355,11 @@ def test_context_isinstance(self): ctx = contextvars.Context() self.assertIsInstance(ctx, collections.abc.Mapping) + mapping_methods = ("__getitem__", "__iter__", "__len__", "__contains__", "keys", + "items", "values", "get", "__eq__", "__ne__") + for name in mapping_methods: + self.assertIn(name, dir(ctx)) + @isolated_context @threading_helper.requires_working_threading() def test_context_threads_1(self): From 3a1f8b222b38674f70403ee708d4a87c99f23666 Mon Sep 17 00:00:00 2001 From: Stephen Morton Date: Tue, 5 Nov 2024 12:37:58 -0800 Subject: [PATCH 03/10] test for callability, sort methods alphabetically in the test --- Lib/test/test_context.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_context.py b/Lib/test/test_context.py index 6af51f7a72da4e..b6bcbb43e7dc3c 100644 --- a/Lib/test/test_context.py +++ b/Lib/test/test_context.py @@ -355,10 +355,12 @@ def test_context_isinstance(self): ctx = contextvars.Context() self.assertIsInstance(ctx, collections.abc.Mapping) - mapping_methods = ("__getitem__", "__iter__", "__len__", "__contains__", "keys", - "items", "values", "get", "__eq__", "__ne__") + mapping_methods = ( + '__contains__', '__eq__', '__getitem__', '__iter__', '__len__', + '__ne__','get', 'items', 'keys', 'values', + ) for name in mapping_methods: - self.assertIn(name, dir(ctx)) + self.assertTrue(callable(getattr(ctx, name))) @isolated_context @threading_helper.requires_working_threading() From 8c68b5b1e4001d9a033b14cec4e986c5ceda2891 Mon Sep 17 00:00:00 2001 From: Stephen Morton Date: Tue, 5 Nov 2024 12:39:16 -0800 Subject: [PATCH 04/10] minor spacing --- Lib/test/test_context.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_context.py b/Lib/test/test_context.py index b6bcbb43e7dc3c..71773c9564a29a 100644 --- a/Lib/test/test_context.py +++ b/Lib/test/test_context.py @@ -357,7 +357,7 @@ def test_context_isinstance(self): mapping_methods = ( '__contains__', '__eq__', '__getitem__', '__iter__', '__len__', - '__ne__','get', 'items', 'keys', 'values', + '__ne__', 'get', 'items', 'keys', 'values', ) for name in mapping_methods: self.assertTrue(callable(getattr(ctx, name))) From aa0da033e846182bf6c515c458c918d41b657367 Mon Sep 17 00:00:00 2001 From: Stephen Morton Date: Tue, 5 Nov 2024 12:53:33 -0800 Subject: [PATCH 05/10] Update Misc/NEWS.d/next/Library/2024-11-05-11-28-45.gh-issue-126451.XJMtqz.rst Co-authored-by: sobolevn --- .../Library/2024-11-05-11-28-45.gh-issue-126451.XJMtqz.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Misc/NEWS.d/next/Library/2024-11-05-11-28-45.gh-issue-126451.XJMtqz.rst b/Misc/NEWS.d/next/Library/2024-11-05-11-28-45.gh-issue-126451.XJMtqz.rst index 0958211ab78aaa..563cb2515eca60 100644 --- a/Misc/NEWS.d/next/Library/2024-11-05-11-28-45.gh-issue-126451.XJMtqz.rst +++ b/Misc/NEWS.d/next/Library/2024-11-05-11-28-45.gh-issue-126451.XJMtqz.rst @@ -1,2 +1,2 @@ -Register the :class:`!contextvars.Context` type to -:class:`!collections.abc.Mapping`. +Register the :class:`contextvars.Context` type to +:class:`collections.abc.Mapping`. From 72d67267e0b7cec65f676effc1742e3b1258c867 Mon Sep 17 00:00:00 2001 From: Stephen Morton Date: Tue, 5 Nov 2024 15:36:36 -0800 Subject: [PATCH 06/10] import _collections_abc instead of collections.abc Co-authored-by: Alex Waygood --- Lib/contextvars.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/contextvars.py b/Lib/contextvars.py index 34a553b6455c2b..14514f185e069d 100644 --- a/Lib/contextvars.py +++ b/Lib/contextvars.py @@ -1,8 +1,8 @@ -import collections.abc +import _collections_abc from _contextvars import Context, ContextVar, Token, copy_context __all__ = ('Context', 'ContextVar', 'Token', 'copy_context') -collections.abc.Mapping.register(Context) +_collections_abc.Mapping.register(Context) From b0c38e8e3e7a5861b7e31bfd0835a7aff40ff4c8 Mon Sep 17 00:00:00 2001 From: Stephen Morton Date: Tue, 5 Nov 2024 15:38:01 -0800 Subject: [PATCH 07/10] use subtests Co-authored-by: Alex Waygood --- Lib/test/test_context.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_context.py b/Lib/test/test_context.py index 71773c9564a29a..232ddb949f955b 100644 --- a/Lib/test/test_context.py +++ b/Lib/test/test_context.py @@ -360,7 +360,8 @@ def test_context_isinstance(self): '__ne__', 'get', 'items', 'keys', 'values', ) for name in mapping_methods: - self.assertTrue(callable(getattr(ctx, name))) + with self.subTest(name=name): + self.assertTrue(callable(getattr(ctx, name))) @isolated_context @threading_helper.requires_working_threading() From 96e2280d1c140b13594fc7d4a4fae3d7a3278b53 Mon Sep 17 00:00:00 2001 From: Stephen Morton Date: Wed, 6 Nov 2024 09:40:01 -0800 Subject: [PATCH 08/10] add issubclass check Co-authored-by: Peter Bierma --- Lib/test/test_context.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/test/test_context.py b/Lib/test/test_context.py index 232ddb949f955b..82d1797ab3b79e 100644 --- a/Lib/test/test_context.py +++ b/Lib/test/test_context.py @@ -354,6 +354,7 @@ def ctx2_fun(): def test_context_isinstance(self): ctx = contextvars.Context() self.assertIsInstance(ctx, collections.abc.Mapping) + self.assertTrue(issubclass(contextvars.Context, collections.abc.Mapping)) mapping_methods = ( '__contains__', '__eq__', '__getitem__', '__iter__', '__len__', From 5cdad6ad7979ac594c77382fd7acf94e51491007 Mon Sep 17 00:00:00 2001 From: Stephen Morton Date: Wed, 6 Nov 2024 09:42:37 -0800 Subject: [PATCH 09/10] Update Lib/test/test_context.py Co-authored-by: Peter Bierma --- Lib/test/test_context.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/test/test_context.py b/Lib/test/test_context.py index 82d1797ab3b79e..da8f9b08b6a808 100644 --- a/Lib/test/test_context.py +++ b/Lib/test/test_context.py @@ -355,6 +355,7 @@ def test_context_isinstance(self): ctx = contextvars.Context() self.assertIsInstance(ctx, collections.abc.Mapping) self.assertTrue(issubclass(contextvars.Context, collections.abc.Mapping)) + self.assertTrue(issubclass(contextvars.Context, collections.abc.Mapping)) mapping_methods = ( '__contains__', '__eq__', '__getitem__', '__iter__', '__len__', From 0e0a5e62444912ce37573f475e22a5bee40d676f Mon Sep 17 00:00:00 2001 From: Stephen Morton Date: Wed, 6 Nov 2024 09:44:19 -0800 Subject: [PATCH 10/10] fix duplicate line --- Lib/test/test_context.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/test/test_context.py b/Lib/test/test_context.py index da8f9b08b6a808..82d1797ab3b79e 100644 --- a/Lib/test/test_context.py +++ b/Lib/test/test_context.py @@ -355,7 +355,6 @@ def test_context_isinstance(self): ctx = contextvars.Context() self.assertIsInstance(ctx, collections.abc.Mapping) self.assertTrue(issubclass(contextvars.Context, collections.abc.Mapping)) - self.assertTrue(issubclass(contextvars.Context, collections.abc.Mapping)) mapping_methods = ( '__contains__', '__eq__', '__getitem__', '__iter__', '__len__',