diff --git a/src/werkzeug/debug/tbtools.py b/src/werkzeug/debug/tbtools.py index 2eadb9e39..c8358882d 100644 --- a/src/werkzeug/debug/tbtools.py +++ b/src/werkzeug/debug/tbtools.py @@ -248,11 +248,11 @@ def __init__(self, exc_type, exc_value, tb): memo = set() while True: self.groups.append(Group(exc_type, exc_value, tb)) - memo.add(exc_value) + memo.add(id(exc_value)) if PY2: break exc_value = exc_value.__cause__ or exc_value.__context__ - if exc_value is None or exc_value in memo: + if exc_value is None or id(exc_value) in memo: break exc_type = type(exc_value) tb = exc_value.__traceback__ diff --git a/tests/test_debug.py b/tests/test_debug.py index 4c4b9746a..84720d666 100644 --- a/tests/test_debug.py +++ b/tests/test_debug.py @@ -371,3 +371,14 @@ def test_chained_exception_cycle(): # if cycles aren't broken, this will time out tb = Traceback(TypeError, error, error.__traceback__) assert len(tb.groups) == 2 + + +def test_non_hashable_exception(): + class MutableException(ValueError): + __hash__ = None + + try: + raise MutableException() + except MutableException: + # previously crashed: `TypeError: unhashable type 'MutableException'` + Traceback(*sys.exc_info())