[3.13] gh-122559: Synchronize C and Python implementation of the io module about pickling (GH-122628) (GH-133381)

In the C implementation, remove __reduce__ and __reduce_ex__ methods
that always raise TypeError and restore __getstate__ methods that always
raise TypeErrori.

This restores fine details of the pre-3.12 behavior and unifies
both implementations.
(cherry picked from commit e9253ebf74)
This commit is contained in:
Serhiy Storchaka 2025-05-04 19:04:09 +03:00 committed by GitHub
parent 3c9d1778ef
commit 973e2d3e29
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 55 additions and 10 deletions

View file

@ -1349,6 +1349,28 @@ class CommonBufferedTests:
with self.assertRaises(AttributeError):
buf.raw = x
def test_pickling_subclass(self):
global MyBufferedIO
class MyBufferedIO(self.tp):
def __init__(self, raw, tag):
super().__init__(raw)
self.tag = tag
def __getstate__(self):
return self.tag, self.raw.getvalue()
def __setstate__(slf, state):
tag, value = state
slf.__init__(self.BytesIO(value), tag)
raw = self.BytesIO(b'data')
buf = MyBufferedIO(raw, tag='ham')
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
with self.subTest(protocol=proto):
pickled = pickle.dumps(buf, proto)
newbuf = pickle.loads(pickled)
self.assertEqual(newbuf.raw.getvalue(), b'data')
self.assertEqual(newbuf.tag, 'ham')
del MyBufferedIO
class SizeofTest:
@ -3932,6 +3954,28 @@ class TextIOWrapperTest(unittest.TestCase):
f.write(res)
self.assertEqual(res + f.readline(), 'foo\nbar\n')
def test_pickling_subclass(self):
global MyTextIO
class MyTextIO(self.TextIOWrapper):
def __init__(self, raw, tag):
super().__init__(raw)
self.tag = tag
def __getstate__(self):
return self.tag, self.buffer.getvalue()
def __setstate__(slf, state):
tag, value = state
slf.__init__(self.BytesIO(value), tag)
raw = self.BytesIO(b'data')
txt = MyTextIO(raw, 'ham')
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
with self.subTest(protocol=proto):
pickled = pickle.dumps(txt, proto)
newtxt = pickle.loads(pickled)
self.assertEqual(newtxt.buffer.getvalue(), b'data')
self.assertEqual(newtxt.tag, 'ham')
del MyTextIO
class MemviewBytesIO(io.BytesIO):
'''A BytesIO object whose read method returns memoryviews