Skip to content

Commit d889afb

Browse files
committed
gh-133982: Test _pyio.BytesIO in free-threaded
The test was only checking one of the two I/O implementations. Ideally the two implementations should match.
1 parent 7afe1ad commit d889afb

File tree

2 files changed

+27
-17
lines changed

2 files changed

+27
-17
lines changed

Lib/test/test_free_threading/test_io.py

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1+
import io
2+
import _pyio as pyio
13
import threading
24
from unittest import TestCase
35
from test.support import threading_helper
46
from random import randint
5-
from io import BytesIO
67
from sys import getsizeof
78

89

9-
class TestBytesIO(TestCase):
10+
class ThreadSafetyMixin:
1011
# Test pretty much everything that can break under free-threading.
1112
# Non-deterministic, but at least one of these things will fail if
1213
# BytesIO object is not free-thread safe.
@@ -90,20 +91,28 @@ def sizeof(barrier, b, *ignore):
9091
barrier.wait()
9192
getsizeof(b)
9293

93-
self.check([write] * 10, BytesIO())
94-
self.check([writelines] * 10, BytesIO())
95-
self.check([write] * 10 + [truncate] * 10, BytesIO())
96-
self.check([truncate] + [read] * 10, BytesIO(b'0\n'*204800))
97-
self.check([truncate] + [read1] * 10, BytesIO(b'0\n'*204800))
98-
self.check([truncate] + [readline] * 10, BytesIO(b'0\n'*20480))
99-
self.check([truncate] + [readlines] * 10, BytesIO(b'0\n'*20480))
100-
self.check([truncate] + [readinto] * 10, BytesIO(b'0\n'*204800), bytearray(b'0\n'*204800))
101-
self.check([close] + [write] * 10, BytesIO())
102-
self.check([truncate] + [getvalue] * 10, BytesIO(b'0\n'*204800))
103-
self.check([truncate] + [getbuffer] * 10, BytesIO(b'0\n'*204800))
104-
self.check([truncate] + [iter] * 10, BytesIO(b'0\n'*20480))
105-
self.check([truncate] + [getstate] * 10, BytesIO(b'0\n'*204800))
106-
self.check([truncate] + [setstate] * 10, BytesIO(b'0\n'*204800), (b'123', 0, None))
107-
self.check([truncate] + [sizeof] * 10, BytesIO(b'0\n'*204800))
94+
self.check([write] * 10, self.ioclass())
95+
self.check([writelines] * 10, self.ioclass())
96+
self.check([write] * 10 + [truncate] * 10, self.ioclass())
97+
self.check([truncate] + [read] * 10, self.ioclass(b'0\n'*204800))
98+
self.check([truncate] + [read1] * 10, self.ioclass(b'0\n'*204800))
99+
self.check([truncate] + [readline] * 10, self.ioclass(b'0\n'*20480))
100+
self.check([truncate] + [readlines] * 10, self.ioclass(b'0\n'*20480))
101+
self.check([truncate] + [readinto] * 10, self.ioclass(b'0\n'*204800), bytearray(b'0\n'*204800))
102+
self.check([close] + [write] * 10, self.ioclass())
103+
self.check([truncate] + [getvalue] * 10, self.ioclass(b'0\n'*204800))
104+
self.check([truncate] + [getbuffer] * 10, self.ioclass(b'0\n'*204800))
105+
self.check([truncate] + [iter] * 10, self.ioclass(b'0\n'*20480))
106+
self.check([truncate] + [getstate] * 10, self.ioclass(b'0\n'*204800))
107+
# _pyio uses default __setstate__
108+
if hasattr(self.ioclass, '__setstate__'):
109+
self.check([truncate] + [setstate] * 10, self.ioclass(b'0\n'*204800), (b'123', 0, None))
110+
self.check([truncate] + [sizeof] * 10, self.ioclass(b'0\n'*204800))
108111

109112
# no tests for seek or tell because they don't break anything
113+
114+
class CBytesIOTest(ThreadSafetyMixin, TestCase):
115+
ioclass = io.BytesIO
116+
117+
class PyBytesIOTest(ThreadSafetyMixin, TestCase):
118+
ioclass = pyio.BytesIO

Lib/test/test_io.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
# * test_univnewlines - tests universal newline support
1010
# * test_largefile - tests operations on a file greater than 2**32 bytes
1111
# (only enabled with -ulargefile)
12+
# * test_free_threading/test_io - tests thread safety of io objects
1213

1314
################################################################################
1415
# ATTENTION TEST WRITERS!!!

0 commit comments

Comments
 (0)