From 080e5542d8fbddd65c26c6b2e3f899511b08f951 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Fri, 4 Jul 2025 15:53:42 +0300 Subject: [PATCH 1/4] gh-136285: Improve `pickle` protocol testing in `test_interpreters` --- Lib/test/test_interpreters/test_api.py | 8 +++++--- Lib/test/test_interpreters/test_channels.py | 16 ++++++++++------ Lib/test/test_interpreters/test_queues.py | 8 +++++--- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/Lib/test/test_interpreters/test_api.py b/Lib/test/test_interpreters/test_api.py index 0ee4582b5d1568..537a3c2067475f 100644 --- a/Lib/test/test_interpreters/test_api.py +++ b/Lib/test/test_interpreters/test_api.py @@ -412,9 +412,11 @@ def test_equality(self): def test_pickle(self): interp = interpreters.create() - data = pickle.dumps(interp) - unpickled = pickle.loads(data) - self.assertEqual(unpickled, interp) + for protocol in range(2, pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(protocol=protocol): + data = pickle.dumps(interp, protocol) + unpickled = pickle.loads(data) + self.assertEqual(unpickled, interp) class TestInterpreterIsRunning(TestBase): diff --git a/Lib/test/test_interpreters/test_channels.py b/Lib/test/test_interpreters/test_channels.py index 109ddf344539ad..d3bfa4ceed3dee 100644 --- a/Lib/test/test_interpreters/test_channels.py +++ b/Lib/test/test_interpreters/test_channels.py @@ -121,9 +121,11 @@ def test_equality(self): def test_pickle(self): ch, _ = channels.create() - data = pickle.dumps(ch) - unpickled = pickle.loads(data) - self.assertEqual(unpickled, ch) + for protocol in range(2, pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(protocol=protocol): + data = pickle.dumps(ch, protocol) + unpickled = pickle.loads(data) + self.assertEqual(unpickled, ch) class TestSendChannelAttrs(TestBase): @@ -152,9 +154,11 @@ def test_equality(self): def test_pickle(self): _, ch = channels.create() - data = pickle.dumps(ch) - unpickled = pickle.loads(data) - self.assertEqual(unpickled, ch) + for protocol in range(2, pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(protocol=protocol): + data = pickle.dumps(ch, protocol) + unpickled = pickle.loads(data) + self.assertEqual(unpickled, ch) class TestSendRecv(TestBase): diff --git a/Lib/test/test_interpreters/test_queues.py b/Lib/test/test_interpreters/test_queues.py index cb17340f581b0a..bfad3f4973a86b 100644 --- a/Lib/test/test_interpreters/test_queues.py +++ b/Lib/test/test_interpreters/test_queues.py @@ -188,9 +188,11 @@ def test_equality(self): def test_pickle(self): queue = queues.create() - data = pickle.dumps(queue) - unpickled = pickle.loads(data) - self.assertEqual(unpickled, queue) + for protocol in range(2, pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(protocol=protocol): + data = pickle.dumps(queue, protocol) + unpickled = pickle.loads(data) + self.assertEqual(unpickled, queue) class TestQueueOps(TestBase): From 8b6fbdec846eeea53a597ec46340712edecb5471 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Sat, 5 Jul 2025 09:43:11 +0300 Subject: [PATCH 2/4] Fix pickling bug --- Lib/concurrent/interpreters/__init__.py | 8 ++------ Lib/concurrent/interpreters/_queues.py | 8 ++------ Lib/test/support/channels.py | 8 ++------ Lib/test/test_interpreters/test_api.py | 2 +- Lib/test/test_interpreters/test_channels.py | 15 ++++++++------- Lib/test/test_interpreters/test_queues.py | 2 +- 6 files changed, 16 insertions(+), 27 deletions(-) diff --git a/Lib/concurrent/interpreters/__init__.py b/Lib/concurrent/interpreters/__init__.py index 0fd661249a276c..aa46a2b37a48d5 100644 --- a/Lib/concurrent/interpreters/__init__.py +++ b/Lib/concurrent/interpreters/__init__.py @@ -146,12 +146,8 @@ def __del__(self): self._decref() # for pickling: - def __getnewargs__(self): - return (self._id,) - - # for pickling: - def __getstate__(self): - return None + def __reduce__(self): + return (type(self), (self._id,)) def _decref(self): if not self._ownsref: diff --git a/Lib/concurrent/interpreters/_queues.py b/Lib/concurrent/interpreters/_queues.py index 99987f2f6926b0..9c12b2c8c24664 100644 --- a/Lib/concurrent/interpreters/_queues.py +++ b/Lib/concurrent/interpreters/_queues.py @@ -129,12 +129,8 @@ def __hash__(self): return hash(self._id) # for pickling: - def __getnewargs__(self): - return (self._id,) - - # for pickling: - def __getstate__(self): - return None + def __reduce__(self): + return (type(self), (self._id,)) def _set_unbound(self, op, items=None): assert not hasattr(self, '_unbound') diff --git a/Lib/test/support/channels.py b/Lib/test/support/channels.py index b2de24d9d3e534..fab1797659b312 100644 --- a/Lib/test/support/channels.py +++ b/Lib/test/support/channels.py @@ -105,12 +105,8 @@ def __eq__(self, other): return other._id == self._id # for pickling: - def __getnewargs__(self): - return (int(self._id),) - - # for pickling: - def __getstate__(self): - return None + def __reduce__(self): + return (type(self), (int(self._id),)) @property def id(self): diff --git a/Lib/test/test_interpreters/test_api.py b/Lib/test/test_interpreters/test_api.py index 537a3c2067475f..a34b20beaca7a3 100644 --- a/Lib/test/test_interpreters/test_api.py +++ b/Lib/test/test_interpreters/test_api.py @@ -412,7 +412,7 @@ def test_equality(self): def test_pickle(self): interp = interpreters.create() - for protocol in range(2, pickle.HIGHEST_PROTOCOL + 1): + for protocol in range(pickle.HIGHEST_PROTOCOL + 1): with self.subTest(protocol=protocol): data = pickle.dumps(interp, protocol) unpickled = pickle.loads(data) diff --git a/Lib/test/test_interpreters/test_channels.py b/Lib/test/test_interpreters/test_channels.py index d3bfa4ceed3dee..f15865df8dc1ec 100644 --- a/Lib/test/test_interpreters/test_channels.py +++ b/Lib/test/test_interpreters/test_channels.py @@ -120,12 +120,13 @@ def test_equality(self): self.assertNotEqual(ch1, ch2) def test_pickle(self): - ch, _ = channels.create() - for protocol in range(2, pickle.HIGHEST_PROTOCOL + 1): - with self.subTest(protocol=protocol): - data = pickle.dumps(ch, protocol) - unpickled = pickle.loads(data) - self.assertEqual(unpickled, ch) + recv, send = channels.create() + for ch in [recv, send]: + for protocol in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(ch=ch, protocol=protocol): + data = pickle.dumps(ch, protocol) + unpickled = pickle.loads(data) + self.assertEqual(unpickled, ch) class TestSendChannelAttrs(TestBase): @@ -154,7 +155,7 @@ def test_equality(self): def test_pickle(self): _, ch = channels.create() - for protocol in range(2, pickle.HIGHEST_PROTOCOL + 1): + for protocol in range(pickle.HIGHEST_PROTOCOL + 1): with self.subTest(protocol=protocol): data = pickle.dumps(ch, protocol) unpickled = pickle.loads(data) diff --git a/Lib/test/test_interpreters/test_queues.py b/Lib/test/test_interpreters/test_queues.py index bfad3f4973a86b..5451c6654acb47 100644 --- a/Lib/test/test_interpreters/test_queues.py +++ b/Lib/test/test_interpreters/test_queues.py @@ -188,7 +188,7 @@ def test_equality(self): def test_pickle(self): queue = queues.create() - for protocol in range(2, pickle.HIGHEST_PROTOCOL + 1): + for protocol in range(pickle.HIGHEST_PROTOCOL + 1): with self.subTest(protocol=protocol): data = pickle.dumps(queue, protocol) unpickled = pickle.loads(data) From b9f6ce6642fd2d4de1bbbcd86fe110eb3c3aeed8 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Sat, 5 Jul 2025 09:45:11 +0300 Subject: [PATCH 3/4] Add NEWS --- .../next/Library/2025-07-05-09-45-04.gh-issue-136286.N67Amr.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2025-07-05-09-45-04.gh-issue-136286.N67Amr.rst diff --git a/Misc/NEWS.d/next/Library/2025-07-05-09-45-04.gh-issue-136286.N67Amr.rst b/Misc/NEWS.d/next/Library/2025-07-05-09-45-04.gh-issue-136286.N67Amr.rst new file mode 100644 index 00000000000000..0a0d66ac0b8abf --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-07-05-09-45-04.gh-issue-136286.N67Amr.rst @@ -0,0 +1,2 @@ +Fix pickling failures for protocols 0 and 1 for many objects realted to +subinterpreters. From 19daa81995ad29e1ec262349bdc5fb57e6d33fc3 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Sun, 6 Jul 2025 10:10:15 +0300 Subject: [PATCH 4/4] Address review --- Lib/test/test_interpreters/test_channels.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Lib/test/test_interpreters/test_channels.py b/Lib/test/test_interpreters/test_channels.py index f15865df8dc1ec..52827357078b85 100644 --- a/Lib/test/test_interpreters/test_channels.py +++ b/Lib/test/test_interpreters/test_channels.py @@ -120,13 +120,12 @@ def test_equality(self): self.assertNotEqual(ch1, ch2) def test_pickle(self): - recv, send = channels.create() - for ch in [recv, send]: - for protocol in range(pickle.HIGHEST_PROTOCOL + 1): - with self.subTest(ch=ch, protocol=protocol): - data = pickle.dumps(ch, protocol) - unpickled = pickle.loads(data) - self.assertEqual(unpickled, ch) + ch, _ = channels.create() + for protocol in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(protocol=protocol): + data = pickle.dumps(ch, protocol) + unpickled = pickle.loads(data) + self.assertEqual(unpickled, ch) class TestSendChannelAttrs(TestBase): pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy