From 0e669f6be532801267d35de23c5f5237b8406d8a Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sun, 12 May 2019 15:01:42 -0700 Subject: [PATCH] Fix unhashable exception types --- src/werkzeug/debug/tbtools.py | 4 ++-- tests/test_debug.py | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) 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())