gh-141732: Fix ExceptionGroup repr changing when original exception sequence is mutated (#141736)

This commit is contained in:
dr-carlos 2025-12-08 07:34:04 +10:30 committed by GitHub
parent dc9f2385ed
commit ff2577f56e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 157 additions and 12 deletions

View file

@ -1,4 +1,4 @@
import collections.abc
import collections
import types
import unittest
from test.support import skip_emscripten_stack_overflow, skip_wasi_stack_overflow, exceeds_recursion_limit
@ -193,6 +193,77 @@ class MyEG(ExceptionGroup):
"MyEG('flat', [ValueError(1), TypeError(2)]), "
"TypeError(2)])"))
def test_exceptions_mutation(self):
class MyEG(ExceptionGroup):
pass
excs = [ValueError(1), TypeError(2)]
eg = MyEG('test', excs)
self.assertEqual(repr(eg), "MyEG('test', [ValueError(1), TypeError(2)])")
excs.clear()
# Ensure that clearing the exceptions sequence doesn't change the repr.
self.assertEqual(repr(eg), "MyEG('test', [ValueError(1), TypeError(2)])")
# Ensure that the args are still as passed.
self.assertEqual(eg.args, ('test', []))
excs = (ValueError(1), KeyboardInterrupt(2))
eg = BaseExceptionGroup('test', excs)
# Ensure that immutable sequences still work fine.
self.assertEqual(
repr(eg),
"BaseExceptionGroup('test', (ValueError(1), KeyboardInterrupt(2)))"
)
# Test non-standard custom sequences.
excs = collections.deque([ValueError(1), TypeError(2)])
eg = ExceptionGroup('test', excs)
self.assertEqual(
repr(eg),
"ExceptionGroup('test', deque([ValueError(1), TypeError(2)]))"
)
excs.clear()
# Ensure that clearing the exceptions sequence doesn't change the repr.
self.assertEqual(
repr(eg),
"ExceptionGroup('test', deque([ValueError(1), TypeError(2)]))"
)
def test_repr_raises(self):
class MySeq(collections.abc.Sequence):
def __init__(self, raises):
self.raises = raises
def __len__(self):
return 1
def __getitem__(self, index):
if index == 0:
return ValueError(1)
raise IndexError
def __repr__(self):
if self.raises:
raise self.raises
return None
seq = MySeq(None)
with self.assertRaisesRegex(
TypeError,
r".*MySeq\.__repr__\(\) must return a str, not NoneType"
):
ExceptionGroup("test", seq)
seq = MySeq(ValueError)
with self.assertRaises(ValueError):
BaseExceptionGroup("test", seq)
def create_simple_eg():
excs = []