diff options
author | Antoine Pitrou <antoine@python.org> | 2020-02-23 22:33:53 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-02-23 22:33:53 (GMT) |
commit | 9f37872e307734666a7169f7be6e3370d3068282 (patch) | |
tree | 47f754a231cd7b028f70577207296847381543b0 /Lib/test/pickletester.py | |
parent | b76518d43fb82ed9e5d27025d18c90a23d525c90 (diff) | |
download | cpython-9f37872e307734666a7169f7be6e3370d3068282.zip cpython-9f37872e307734666a7169f7be6e3370d3068282.tar.gz cpython-9f37872e307734666a7169f7be6e3370d3068282.tar.bz2 |
bpo-39681: Fix C pickle regression with minimal file-like objects (#18592)
Fix a regression where the C pickle module wouldn't allow unpickling from a
file-like object that doesn't expose a readinto() method.
Diffstat (limited to 'Lib/test/pickletester.py')
-rw-r--r-- | Lib/test/pickletester.py | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py index ba893f3..6ef4c89 100644 --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -73,6 +73,18 @@ class UnseekableIO(io.BytesIO): raise io.UnsupportedOperation +class MinimalIO(object): + """ + A file-like object that doesn't support readinto(). + """ + def __init__(self, *args): + self._bio = io.BytesIO(*args) + self.getvalue = self._bio.getvalue + self.read = self._bio.read + self.readline = self._bio.readline + self.write = self._bio.write + + # We can't very well test the extension registry without putting known stuff # in it, but we have to be careful to restore its original state. Code # should do this: @@ -3363,7 +3375,7 @@ class AbstractPicklerUnpicklerObjectTests(unittest.TestCase): f.seek(0) self.assertEqual(unpickler.load(), data2) - def _check_multiple_unpicklings(self, ioclass): + def _check_multiple_unpicklings(self, ioclass, *, seekable=True): for proto in protocols: with self.subTest(proto=proto): data1 = [(x, str(x)) for x in range(2000)] + [b"abcde", len] @@ -3376,10 +3388,10 @@ class AbstractPicklerUnpicklerObjectTests(unittest.TestCase): f = ioclass(pickled * N) unpickler = self.unpickler_class(f) for i in range(N): - if f.seekable(): + if seekable: pos = f.tell() self.assertEqual(unpickler.load(), data1) - if f.seekable(): + if seekable: self.assertEqual(f.tell(), pos + len(pickled)) self.assertRaises(EOFError, unpickler.load) @@ -3387,7 +3399,12 @@ class AbstractPicklerUnpicklerObjectTests(unittest.TestCase): self._check_multiple_unpicklings(io.BytesIO) def test_multiple_unpicklings_unseekable(self): - self._check_multiple_unpicklings(UnseekableIO) + self._check_multiple_unpicklings(UnseekableIO, seekable=False) + + def test_multiple_unpicklings_minimal(self): + # File-like object that doesn't support peek() and readinto() + # (bpo-39681) + self._check_multiple_unpicklings(MinimalIO, seekable=False) def test_unpickling_buffering_readline(self): # Issue #12687: the unpickler's buffering logic could fail with |