gh-98458: unittest: bugfix for infinite loop while handling chained exceptions that contain cycles (GH-98459)

* Bugfix addressing infinite loop while handling self-referencing chained exception in TestResult._clean_tracebacks()
* Bugfix extended to properly handle exception cycles in _clean_tracebacks. The "seen" set follows the approach used in the TracebackException class (thank you @iritkatriel for pointing it out)
* adds a test for a single chained exception that holds a self-loop in its __cause__ and __context__ attributes
(cherry picked from commit 72ec518203)

Co-authored-by: AlexTate <0xalextate@gmail.com>
This commit is contained in:
Miss Islington (bot) 2022-12-04 12:06:42 -08:00 committed by GitHub
parent 7aa87bba05
commit 9bcc68b045
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 60 additions and 1 deletions

View file

@ -196,6 +196,7 @@ class TestResult(object):
ret = None
first = True
excs = [(exctype, value, tb)]
seen = {id(value)} # Detect loops in chained exceptions.
while excs:
(exctype, value, tb) = excs.pop()
# Skip test runner traceback levels
@ -214,8 +215,9 @@ class TestResult(object):
if value is not None:
for c in (value.__cause__, value.__context__):
if c is not None:
if c is not None and id(c) not in seen:
excs.append((type(c), c, c.__traceback__))
seen.add(id(c))
return ret
def _is_relevant_tb_level(self, tb):