From 26ffe7490bf6bcce6b588f59c155bcd16d7f0f07 Mon Sep 17 00:00:00 2001 From: Yongtao Huang Date: Mon, 15 Dec 2025 16:05:54 +0800 Subject: [PATCH 1/6] Fix ABC registration for SetProxy in multiprocessing.managers Register _BaseSetProxy as MutableSet instead of MutableMapping. SetProxy implements set semantics and does not implement the mapping protocol, so the previous ABC registration caused incorrect type classification. Signed-off-by: Yongtao Huang --- Lib/multiprocessing/managers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/multiprocessing/managers.py b/Lib/multiprocessing/managers.py index 91bcf243e78e5b8..73452c2140b0181 100644 --- a/Lib/multiprocessing/managers.py +++ b/Lib/multiprocessing/managers.py @@ -1224,7 +1224,7 @@ def __isub__(self, value): __class_getitem__ = classmethod(types.GenericAlias) -collections.abc.MutableMapping.register(_BaseSetProxy) +collections.abc.MutableSet.register(_BaseSetProxy) ArrayProxy = MakeProxyType('ArrayProxy', ( From 596da3c68a2737af1186e64b4f367a0ff332f4ad Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Thu, 18 Dec 2025 10:37:02 +0000 Subject: [PATCH 2/6] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/Library/2025-12-18-10-37-01.gh-issue-142740.Di48Rf.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2025-12-18-10-37-01.gh-issue-142740.Di48Rf.rst diff --git a/Misc/NEWS.d/next/Library/2025-12-18-10-37-01.gh-issue-142740.Di48Rf.rst b/Misc/NEWS.d/next/Library/2025-12-18-10-37-01.gh-issue-142740.Di48Rf.rst new file mode 100644 index 000000000000000..383407738c66d41 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-12-18-10-37-01.gh-issue-142740.Di48Rf.rst @@ -0,0 +1 @@ +Register ``multiprocessing.managers.SetProxy`` as ``collections.abc.MutableSet`` rather than ``MutableMapping``. From 7e7abda9b92a1949bfe4e7f0830e86788516c060 Mon Sep 17 00:00:00 2001 From: Yongtao Huang Date: Thu, 18 Dec 2025 19:42:02 +0800 Subject: [PATCH 3/6] Add test case --- Lib/test/_test_multiprocessing.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index d03eb1dfb253ec3..cd61dc7a302a479 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -2786,6 +2786,31 @@ def test_dict_proxy_nested(self): self.assertIsInstance(outer[0], list) # Not a ListProxy self.assertEqual(outer[-1][-1]['feed'], 3) + def test_set_isinstance(self): + m = multiprocessing.Manager() + self.addCleanup(m.shutdown) + s = m.set() + self.assertIsInstance(s, collections.abc.MutableSet) + self.assertNotIsInstance(s, collections.abc.MutableMapping) + + mutable_set_methods = ( + '__contains__', '__iter__', '__len__', + 'add', 'discard', 'remove', 'pop', 'clear', + 'update', 'difference_update', 'intersection_update', + 'symmetric_difference_update', + ) + for name in mutable_set_methods: + with self.subTest(name=name): + self.assertTrue(callable(getattr(s, name))) + + mapping_only_methods = ( + '__getitem__', '__setitem__', 'setdefault', + 'keys', 'items', 'values', 'get', + ) + for name in mapping_only_methods: + with self.subTest(name=name): + self.assertFalse(hasattr(s, name)) + def test_nested_queue(self): a = self.list() # Test queue inside list a.append(self.Queue()) From 353caaabf17659f5f552f74a4acd1bacae0c1b08 Mon Sep 17 00:00:00 2001 From: Yongtao Huang Date: Thu, 18 Dec 2025 21:09:42 +0800 Subject: [PATCH 4/6] Fix test case --- Lib/test/_test_multiprocessing.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index cd61dc7a302a479..3ce0bc55ede1c44 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -2787,9 +2787,7 @@ def test_dict_proxy_nested(self): self.assertEqual(outer[-1][-1]['feed'], 3) def test_set_isinstance(self): - m = multiprocessing.Manager() - self.addCleanup(m.shutdown) - s = m.set() + s = self.set() self.assertIsInstance(s, collections.abc.MutableSet) self.assertNotIsInstance(s, collections.abc.MutableMapping) @@ -7156,6 +7154,7 @@ class ManagerMixin(BaseMixin): Array = property(operator.attrgetter('manager.Array')) list = property(operator.attrgetter('manager.list')) dict = property(operator.attrgetter('manager.dict')) + set = property(operator.attrgetter('manager.set')) Namespace = property(operator.attrgetter('manager.Namespace')) @classmethod From 6c57ea00650a47ed612f60fbe6ea1b3dfe214bbf Mon Sep 17 00:00:00 2001 From: Yongtao Huang Date: Fri, 28 Aug 2026 21:51:52 +0800 Subject: [PATCH 5/6] Apply suggestion from @aisk Co-authored-by: An Long --- .../Library/2025-12-18-10-37-01.gh-issue-142740.Di48Rf.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2025-12-18-10-37-01.gh-issue-142740.Di48Rf.rst b/Misc/NEWS.d/next/Library/2025-12-18-10-37-01.gh-issue-142740.Di48Rf.rst index 383407738c66d41..389704bc9288263 100644 --- a/Misc/NEWS.d/next/Library/2025-12-18-10-37-01.gh-issue-142740.Di48Rf.rst +++ b/Misc/NEWS.d/next/Library/2025-12-18-10-37-01.gh-issue-142740.Di48Rf.rst @@ -1 +1,3 @@ -Register ``multiprocessing.managers.SetProxy`` as ``collections.abc.MutableSet`` rather than ``MutableMapping``. +Register :class:`!multiprocessing.managers.SetProxy` as +:class:`collections.abc.MutableSet` rather than +:class:`~collections.abc.MutableMapping`. From 61aec195a8ab388240dfeab8a72c22bafde8bd16 Mon Sep 17 00:00:00 2001 From: Yongtao Huang Date: Fri, 28 Aug 2026 21:56:05 +0800 Subject: [PATCH 6/6] Resolve comments Removed no need tests for mutable set from the multiprocessing test suite. --- Lib/test/_test_multiprocessing.py | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index 3ce0bc55ede1c44..ba4fbc905c348f1 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -2791,24 +2791,6 @@ def test_set_isinstance(self): self.assertIsInstance(s, collections.abc.MutableSet) self.assertNotIsInstance(s, collections.abc.MutableMapping) - mutable_set_methods = ( - '__contains__', '__iter__', '__len__', - 'add', 'discard', 'remove', 'pop', 'clear', - 'update', 'difference_update', 'intersection_update', - 'symmetric_difference_update', - ) - for name in mutable_set_methods: - with self.subTest(name=name): - self.assertTrue(callable(getattr(s, name))) - - mapping_only_methods = ( - '__getitem__', '__setitem__', 'setdefault', - 'keys', 'items', 'values', 'get', - ) - for name in mapping_only_methods: - with self.subTest(name=name): - self.assertFalse(hasattr(s, name)) - def test_nested_queue(self): a = self.list() # Test queue inside list a.append(self.Queue())