Skip to content

Commit d7bf513

Browse files
committed
Remove wrapper_ref, use simpler classes, wrapper local only
1 parent c0bdd84 commit d7bf513

1 file changed

Lines changed: 22 additions & 23 deletions

File tree

Lib/test/test_io/test_textio.py

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1567,24 +1567,20 @@ def closed(self):
15671567
def test_reentrant_detach_during_flush(self):
15681568
# gh-143008: Reentrant detach() during flush should not crash.
15691569
wrapper = None
1570-
wrapper_ref = lambda: None
1571-
1572-
class EvilBuffer(self.BufferedRandom):
1573-
detach_on_write = False
15741570

1571+
class DetachOnFlush(self.BufferedRandom):
15751572
def flush(self):
1576-
wrapper = wrapper_ref()
1577-
if wrapper is not None and not self.detach_on_write:
1573+
if wrapper is not None:
15781574
wrapper.detach()
15791575
return super().flush()
15801576

1577+
class DetachOnWrite(self.BufferedRandom):
15811578
def write(self, b):
1582-
wrapper = wrapper_ref()
1583-
if wrapper is not None and self.detach_on_write:
1579+
if wrapper is not None:
15841580
wrapper.detach()
15851581
return len(b)
15861582

1587-
# Many calls could result in the same null self->buffer crash.
1583+
# Used to crash; now will run out of stack.
15881584
tests = [
15891585
('truncate', lambda: wrapper.truncate(0)),
15901586
('close', lambda: wrapper.close()),
@@ -1593,23 +1589,26 @@ def write(self, b):
15931589
('tell', lambda: wrapper.tell()),
15941590
('reconfigure', lambda: wrapper.reconfigure(line_buffering=True)),
15951591
]
1596-
for name, method in tests:
1592+
for name, call in tests:
15971593
with self.subTest(name), set_recursion_limit(100):
1598-
wrapper = self.TextIOWrapper(EvilBuffer(self.MockRawIO()), encoding='utf-8')
1599-
wrapper_ref = weakref.ref(wrapper)
1600-
# Used to crash; now will run out of stack.
1601-
self.assertRaises(RecursionError, method)
1602-
wrapper_ref = lambda: None
1603-
del wrapper
1594+
buffer = DetachOnFlush(self.MockRawIO())
1595+
wrapper = self.TextIOWrapper(buffer, encoding='utf-8')
1596+
try:
1597+
self.assertRaises(RecursionError, call)
1598+
finally:
1599+
# Disarm before GC so finalization succeeds.
1600+
wrapper = None
16041601

1602+
# Used to crash.
16051603
with self.subTest('read via writeflush'):
1606-
EvilBuffer.detach_on_write = True
1607-
wrapper = self.TextIOWrapper(EvilBuffer(self.MockRawIO()), encoding='utf-8')
1608-
wrapper_ref = weakref.ref(wrapper)
1609-
wrapper.write('x')
1610-
self.assertRaisesRegex(ValueError, "detached", wrapper.read)
1611-
wrapper_ref = lambda: None
1612-
del wrapper
1604+
buffer = DetachOnWrite(self.MockRawIO())
1605+
wrapper = self.TextIOWrapper(buffer, encoding='utf-8')
1606+
try:
1607+
wrapper.write('x')
1608+
self.assertRaisesRegex(ValueError, "detached", wrapper.read)
1609+
finally:
1610+
# Disarm before GC so finalization succeeds.
1611+
wrapper = None
16131612

16141613

16151614
class PyTextIOWrapperTest(TextIOWrapperTest, PyTestCase):

0 commit comments

Comments
 (0)