Skip to content

Commit bdc17e4

Browse files
authored
Merge pull request #1540 from pallets/break-tb-cycle
break cycle in chained exceptions
2 parents 777500b + 44e38c2 commit bdc17e4

File tree

4 files changed

+23
-1
lines changed

4 files changed

+23
-1
lines changed

CHANGES.rst

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ Unreleased
1818
float values. (:issue:`1511`)
1919
- Update :class:`~middleware.lint.LintMiddleware` to work on Python 3.
2020
(:issue:`1510`)
21+
- The debugger detects cycles in chained exceptions and does not time
22+
out in that case. (:issue:`1536`)
2123

2224

2325
Version 0.15.2

src/werkzeug/debug/tbtools.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -245,12 +245,14 @@ def __init__(self, exc_type, exc_value, tb):
245245
self.exception_type = exception_type
246246

247247
self.groups = []
248+
memo = set()
248249
while True:
249250
self.groups.append(Group(exc_type, exc_value, tb))
251+
memo.add(exc_value)
250252
if PY2:
251253
break
252254
exc_value = exc_value.__cause__ or exc_value.__context__
253-
if exc_value is None:
255+
if exc_value is None or exc_value in memo:
254256
break
255257
exc_type = type(exc_value)
256258
tb = exc_value.__traceback__

tests/test_debug.py

+17
Original file line numberDiff line numberDiff line change
@@ -354,3 +354,20 @@ def app(environ, start_response):
354354
assert "The debugger caught an exception in your WSGI application" in r.text
355355
else:
356356
assert r.text == "hello"
357+
358+
359+
@pytest.mark.skipif(PY2, reason="Python 2 doesn't have chained exceptions.")
360+
@pytest.mark.timeout(2)
361+
def test_chained_exception_cycle():
362+
try:
363+
try:
364+
raise ValueError()
365+
except ValueError:
366+
raise TypeError()
367+
except TypeError as e:
368+
# create a cycle and make it available outside the except block
369+
e.__context__.__context__ = error = e
370+
371+
# if cycles aren't broken, this will time out
372+
tb = Traceback(TypeError, error, error.__traceback__)
373+
assert len(tb.groups) == 2

tox.ini

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ skip_missing_interpreters = true
1010
deps =
1111
coverage
1212
pytest
13+
pytest-timeout
1314
pytest-xprocess
1415
requests
1516
requests_unixsocket

0 commit comments

Comments
 (0)