From c8c5f15a0829e6d6c9d679b4ce21155c37416668 Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Wed, 15 Nov 2017 13:44:49 -0500 Subject: [PATCH 1/3] bpo-32034: Make asyncio.IncompleteReadError pickleable. --- Lib/asyncio/streams.py | 3 +++ Lib/test/test_asyncio/test_streams.py | 8 ++++++++ .../next/Library/2017-11-15-13-44-28.bpo-32034.uHAOmu.rst | 1 + 3 files changed, 12 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2017-11-15-13-44-28.bpo-32034.uHAOmu.rst diff --git a/Lib/asyncio/streams.py b/Lib/asyncio/streams.py index 9fda8537686d0a..7ab985b330eeaa 100644 --- a/Lib/asyncio/streams.py +++ b/Lib/asyncio/streams.py @@ -35,6 +35,9 @@ def __init__(self, partial, expected): self.partial = partial self.expected = expected + def __reduce__(self): + return type(self), (self.partial, self.expected) + class LimitOverrunError(Exception): """Reached the buffer limit while looking for a separator. diff --git a/Lib/test/test_asyncio/test_streams.py b/Lib/test/test_asyncio/test_streams.py index b47433a4cfdbd4..4212a015881dbe 100644 --- a/Lib/test/test_asyncio/test_streams.py +++ b/Lib/test/test_asyncio/test_streams.py @@ -3,6 +3,7 @@ import gc import os import queue +import pickle import socket import sys import threading @@ -845,6 +846,13 @@ def test___repr__transport(self): stream._transport.__repr__.return_value = "" self.assertEqual(">", repr(stream)) + def test_IncompleteReadError_pickleable(self): + e = asyncio.IncompleteReadError(b'abc', 10) + e2 = pickle.loads(pickle.dumps(e)) + self.assertEqual(str(e), str(e2)) + self.assertEqual(e.partial, e2.partial) + self.assertEqual(e.expected, e2.expected) + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS.d/next/Library/2017-11-15-13-44-28.bpo-32034.uHAOmu.rst b/Misc/NEWS.d/next/Library/2017-11-15-13-44-28.bpo-32034.uHAOmu.rst new file mode 100644 index 00000000000000..7c5a8d785ac796 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-11-15-13-44-28.bpo-32034.uHAOmu.rst @@ -0,0 +1 @@ +Make asyncio.IncompleteReadError pickleable. From c94b5b178faa2245a7630115624acb060de053fa Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Wed, 15 Nov 2017 14:58:18 -0500 Subject: [PATCH 2/3] Make LimitOverrunError pickleable too --- Lib/asyncio/streams.py | 3 +++ Lib/test/test_asyncio/test_streams.py | 6 ++++++ .../next/Library/2017-11-15-13-44-28.bpo-32034.uHAOmu.rst | 2 +- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Lib/asyncio/streams.py b/Lib/asyncio/streams.py index 7ab985b330eeaa..30b751e9891b38 100644 --- a/Lib/asyncio/streams.py +++ b/Lib/asyncio/streams.py @@ -49,6 +49,9 @@ def __init__(self, message, consumed): super().__init__(message) self.consumed = consumed + def __reduce__(self): + return type(self), (self.args[0], self.consumed) + @coroutine def open_connection(host=None, port=None, *, diff --git a/Lib/test/test_asyncio/test_streams.py b/Lib/test/test_asyncio/test_streams.py index 4212a015881dbe..1d94f702833b8d 100644 --- a/Lib/test/test_asyncio/test_streams.py +++ b/Lib/test/test_asyncio/test_streams.py @@ -853,6 +853,12 @@ def test_IncompleteReadError_pickleable(self): self.assertEqual(e.partial, e2.partial) self.assertEqual(e.expected, e2.expected) + def test_LimitOverrunError_pickleable(self): + e = asyncio.LimitOverrunError('message', 10) + e2 = pickle.loads(pickle.dumps(e)) + self.assertEqual(str(e), str(e2)) + self.assertEqual(e.consumed, e2.consumed) + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS.d/next/Library/2017-11-15-13-44-28.bpo-32034.uHAOmu.rst b/Misc/NEWS.d/next/Library/2017-11-15-13-44-28.bpo-32034.uHAOmu.rst index 7c5a8d785ac796..828e8cde571383 100644 --- a/Misc/NEWS.d/next/Library/2017-11-15-13-44-28.bpo-32034.uHAOmu.rst +++ b/Misc/NEWS.d/next/Library/2017-11-15-13-44-28.bpo-32034.uHAOmu.rst @@ -1 +1 @@ -Make asyncio.IncompleteReadError pickleable. +Make asyncio.IncompleteReadError and LimitOverrunError pickleable. From b6984462847407f4d281a4845b35d419e48903f7 Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Wed, 15 Nov 2017 15:01:54 -0500 Subject: [PATCH 3/3] Test all pickle protocols --- Lib/test/test_asyncio/test_streams.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/Lib/test/test_asyncio/test_streams.py b/Lib/test/test_asyncio/test_streams.py index 1d94f702833b8d..6d16d2007967d3 100644 --- a/Lib/test/test_asyncio/test_streams.py +++ b/Lib/test/test_asyncio/test_streams.py @@ -848,16 +848,20 @@ def test___repr__transport(self): def test_IncompleteReadError_pickleable(self): e = asyncio.IncompleteReadError(b'abc', 10) - e2 = pickle.loads(pickle.dumps(e)) - self.assertEqual(str(e), str(e2)) - self.assertEqual(e.partial, e2.partial) - self.assertEqual(e.expected, e2.expected) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(pickle_protocol=proto): + e2 = pickle.loads(pickle.dumps(e, protocol=proto)) + self.assertEqual(str(e), str(e2)) + self.assertEqual(e.partial, e2.partial) + self.assertEqual(e.expected, e2.expected) def test_LimitOverrunError_pickleable(self): e = asyncio.LimitOverrunError('message', 10) - e2 = pickle.loads(pickle.dumps(e)) - self.assertEqual(str(e), str(e2)) - self.assertEqual(e.consumed, e2.consumed) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(pickle_protocol=proto): + e2 = pickle.loads(pickle.dumps(e, protocol=proto)) + self.assertEqual(str(e), str(e2)) + self.assertEqual(e.consumed, e2.consumed) if __name__ == '__main__':