Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 973e2d3

Browse filesBrowse files
[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 e9253eb)
1 parent 3c9d177 commit 973e2d3
Copy full SHA for 973e2d3

File tree

5 files changed

+55
-10
lines changed
Filter options

5 files changed

+55
-10
lines changed

‎Lib/test/test_io.py

Copy file name to clipboardExpand all lines: Lib/test/test_io.py
+44Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1349,6 +1349,28 @@ def test_readonly_attributes(self):
13491349
with self.assertRaises(AttributeError):
13501350
buf.raw = x
13511351

1352+
def test_pickling_subclass(self):
1353+
global MyBufferedIO
1354+
class MyBufferedIO(self.tp):
1355+
def __init__(self, raw, tag):
1356+
super().__init__(raw)
1357+
self.tag = tag
1358+
def __getstate__(self):
1359+
return self.tag, self.raw.getvalue()
1360+
def __setstate__(slf, state):
1361+
tag, value = state
1362+
slf.__init__(self.BytesIO(value), tag)
1363+
1364+
raw = self.BytesIO(b'data')
1365+
buf = MyBufferedIO(raw, tag='ham')
1366+
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1367+
with self.subTest(protocol=proto):
1368+
pickled = pickle.dumps(buf, proto)
1369+
newbuf = pickle.loads(pickled)
1370+
self.assertEqual(newbuf.raw.getvalue(), b'data')
1371+
self.assertEqual(newbuf.tag, 'ham')
1372+
del MyBufferedIO
1373+
13521374

13531375
class SizeofTest:
13541376

@@ -3932,6 +3954,28 @@ def test_issue35928(self):
39323954
f.write(res)
39333955
self.assertEqual(res + f.readline(), 'foo\nbar\n')
39343956

3957+
def test_pickling_subclass(self):
3958+
global MyTextIO
3959+
class MyTextIO(self.TextIOWrapper):
3960+
def __init__(self, raw, tag):
3961+
super().__init__(raw)
3962+
self.tag = tag
3963+
def __getstate__(self):
3964+
return self.tag, self.buffer.getvalue()
3965+
def __setstate__(slf, state):
3966+
tag, value = state
3967+
slf.__init__(self.BytesIO(value), tag)
3968+
3969+
raw = self.BytesIO(b'data')
3970+
txt = MyTextIO(raw, 'ham')
3971+
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
3972+
with self.subTest(protocol=proto):
3973+
pickled = pickle.dumps(txt, proto)
3974+
newtxt = pickle.loads(pickled)
3975+
self.assertEqual(newtxt.buffer.getvalue(), b'data')
3976+
self.assertEqual(newtxt.tag, 'ham')
3977+
del MyTextIO
3978+
39353979

39363980
class MemviewBytesIO(io.BytesIO):
39373981
'''A BytesIO object whose read method returns memoryviews
+6Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Remove :meth:`!__reduce__` and :meth:`!__reduce_ex__` methods that always
2+
raise :exc:`TypeError` in the C implementation of :class:`io.FileIO`,
3+
:class:`io.BufferedReader`, :class:`io.BufferedWriter` and
4+
:class:`io.BufferedRandom` and replace them with default
5+
:meth:`!__getstate__` methods that raise :exc:`!TypeError`.
6+
This restores fine details of behavior of Python 3.11 and older versions.

‎Modules/_io/bufferedio.c

Copy file name to clipboardExpand all lines: Modules/_io/bufferedio.c
+3-6Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2530,8 +2530,7 @@ static PyMethodDef bufferedreader_methods[] = {
25302530
_IO__BUFFERED_TRUNCATE_METHODDEF
25312531
_IO__BUFFERED___SIZEOF___METHODDEF
25322532

2533-
{"__reduce__", _PyIOBase_cannot_pickle, METH_NOARGS},
2534-
{"__reduce_ex__", _PyIOBase_cannot_pickle, METH_O},
2533+
{"__getstate__", _PyIOBase_cannot_pickle, METH_NOARGS},
25352534
{NULL, NULL}
25362535
};
25372536

@@ -2590,8 +2589,7 @@ static PyMethodDef bufferedwriter_methods[] = {
25902589
_IO__BUFFERED_TELL_METHODDEF
25912590
_IO__BUFFERED___SIZEOF___METHODDEF
25922591

2593-
{"__reduce__", _PyIOBase_cannot_pickle, METH_NOARGS},
2594-
{"__reduce_ex__", _PyIOBase_cannot_pickle, METH_O},
2592+
{"__getstate__", _PyIOBase_cannot_pickle, METH_NOARGS},
25952593
{NULL, NULL}
25962594
};
25972595

@@ -2708,8 +2706,7 @@ static PyMethodDef bufferedrandom_methods[] = {
27082706
_IO_BUFFEREDWRITER_WRITE_METHODDEF
27092707
_IO__BUFFERED___SIZEOF___METHODDEF
27102708

2711-
{"__reduce__", _PyIOBase_cannot_pickle, METH_NOARGS},
2712-
{"__reduce_ex__", _PyIOBase_cannot_pickle, METH_O},
2709+
{"__getstate__", _PyIOBase_cannot_pickle, METH_NOARGS},
27132710
{NULL, NULL}
27142711
};
27152712

‎Modules/_io/fileio.c

Copy file name to clipboardExpand all lines: Modules/_io/fileio.c
+1-2Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1178,8 +1178,7 @@ static PyMethodDef fileio_methods[] = {
11781178
_IO_FILEIO_FILENO_METHODDEF
11791179
_IO_FILEIO_ISATTY_METHODDEF
11801180
{"_dealloc_warn", (PyCFunction)fileio_dealloc_warn, METH_O, NULL},
1181-
{"__reduce__", _PyIOBase_cannot_pickle, METH_NOARGS},
1182-
{"__reduce_ex__", _PyIOBase_cannot_pickle, METH_O},
1181+
{"__getstate__", _PyIOBase_cannot_pickle, METH_NOARGS},
11831182
{NULL, NULL} /* sentinel */
11841183
};
11851184

‎Modules/_io/textio.c

Copy file name to clipboardExpand all lines: Modules/_io/textio.c
+1-2Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3350,8 +3350,7 @@ static PyMethodDef textiowrapper_methods[] = {
33503350
_IO_TEXTIOWRAPPER_TELL_METHODDEF
33513351
_IO_TEXTIOWRAPPER_TRUNCATE_METHODDEF
33523352

3353-
{"__reduce__", _PyIOBase_cannot_pickle, METH_NOARGS},
3354-
{"__reduce_ex__", _PyIOBase_cannot_pickle, METH_O},
3353+
{"__getstate__", _PyIOBase_cannot_pickle, METH_NOARGS},
33553354
{NULL, NULL}
33563355
};
33573356

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.