From 55533c95c6f30d8f88db847fb3f01d7ddb57b280 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= Date: Tue, 1 Sep 2020 13:37:49 +0200 Subject: [PATCH] Ignore exception classes which are not types Fixes #135 --- bugbear.py | 12 +++++++++++- tests/b014.py | 8 ++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/bugbear.py b/bugbear.py index 63f7919..b064958 100644 --- a/bugbear.py +++ b/bugbear.py @@ -130,6 +130,16 @@ def _to_name_str(node): return _to_name_str(node.value) + "." + node.attr +def _typesafe_issubclass(cls, class_or_tuple): + try: + return issubclass(cls, class_or_tuple) + except TypeError: + # User code specifies a type that is not a type in our current run. Might be + # their error, might be a difference in our environments. We don't know so we + # ignore this + return False + + @attr.s class BugBearVisitor(ast.NodeVisitor): filename = attr.ib() @@ -190,7 +200,7 @@ def visit_ExceptHandler(self, node): good = list(filter(lambda e: e not in aliases, good)) for name, other in itertools.permutations(tuple(good), 2): - if issubclass( + if _typesafe_issubclass( getattr(builtins, name, type), getattr(builtins, other, ()) ): if name in good: diff --git a/tests/b014.py b/tests/b014.py index a3e64e6..fe828a3 100644 --- a/tests/b014.py +++ b/tests/b014.py @@ -59,3 +59,11 @@ class MyError(Exception): # socket.error and select.error are aliases of OSError. See PEP 3151 for # more info. pass + + +try: + pass +except (MyException, NotImplemented): + # NotImplemented is not an exception, let's not crash on it. + pass +