Skip to content

Commit

Permalink
B014: catch binascii.Error and ValueError redundancy + cleanup (#206)
Browse files Browse the repository at this point in the history
I am honestly a bit embarrassed by my old code. Let's fix it up with
better comments and clearer names.
  • Loading branch information
ichard26 committed Nov 27, 2021
1 parent 71091f9 commit c90fa65
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 16 deletions.
6 changes: 6 additions & 0 deletions README.rst
Expand Up @@ -224,6 +224,12 @@ MIT
Change Log
----------

Unreleased
~~~~~~~~~~

* Update B014: ``binascii.Error`` is now treated as a subclass of ``ValueError``
(#206)

21.9.2
~~~~~~~~~~

Expand Down
21 changes: 12 additions & 9 deletions bugbear.py
Expand Up @@ -193,13 +193,12 @@ def visit_ExceptHandler(self, node):
good = sorted(set(names), key=names.index)
if "BaseException" in good:
good = ["BaseException"]
# Find and remove aliases exceptions and only leave the primary alone
primaries = filter(
lambda primary: primary in good, B014.exception_aliases.keys()
)
for primary in primaries:
aliases = B014.exception_aliases[primary]
good = list(filter(lambda e: e not in aliases, good))
# Remove redundant exceptions that the automatic system either handles
# poorly (usually aliases) or can't be checked (e.g. it's not an
# built-in exception).
for primary, equivalents in B014.redundant_exceptions.items():
if primary in good:
good = [g for g in good if g not in equivalents]

for name, other in itertools.permutations(tuple(good), 2):
if _typesafe_issubclass(
Expand Down Expand Up @@ -758,15 +757,19 @@ def visit(self, node):
"Write `except {2}{1}:`, which catches exactly the same exceptions."
)
)
B014.exception_aliases = {
B014.redundant_exceptions = {
"OSError": {
# All of these are actually aliases of OSError since Python 3.3
"IOError",
"EnvironmentError",
"WindowsError",
"mmap.error",
"socket.error",
"select.error",
}
},
"ValueError": {
"binascii.Error",
},
}
B015 = Error(
message=(
Expand Down
10 changes: 9 additions & 1 deletion tests/b014.py
@@ -1,8 +1,9 @@
"""
Should emit:
B014 - on lines 10, 16, 27, 41, 48, and 55
B014 - on lines 11, 17, 28, 42, 49, 56, and 74.
"""

import binascii
import re

try:
Expand Down Expand Up @@ -66,3 +67,10 @@ class MyError(Exception):
except (MyException, NotImplemented):
# NotImplemented is not an exception, let's not crash on it.
pass


try:
pass
except (ValueError, binascii.Error):
# binascii.Error is a subclass of ValueError.
pass
13 changes: 7 additions & 6 deletions tests/test_bugbear.py
Expand Up @@ -179,16 +179,17 @@ def test_b014(self):
bbc = BugBearChecker(filename=str(filename))
errors = list(bbc.run())
expected = self.errors(
B014(10, 0, vars=("Exception, TypeError", "", "Exception")),
B014(16, 0, vars=("OSError, OSError", " as err", "OSError")),
B014(27, 0, vars=("MyError, MyError", "", "MyError")),
B014(41, 0, vars=("MyError, BaseException", " as e", "BaseException")),
B014(48, 0, vars=("re.error, re.error", "", "re.error")),
B014(11, 0, vars=("Exception, TypeError", "", "Exception")),
B014(17, 0, vars=("OSError, OSError", " as err", "OSError")),
B014(28, 0, vars=("MyError, MyError", "", "MyError")),
B014(42, 0, vars=("MyError, BaseException", " as e", "BaseException")),
B014(49, 0, vars=("re.error, re.error", "", "re.error")),
B014(
55,
56,
0,
vars=("IOError, EnvironmentError, OSError", "", "OSError"),
),
B014(74, 0, vars=("ValueError, binascii.Error", "", "ValueError")),
)
self.assertEqual(errors, expected)

Expand Down

0 comments on commit c90fa65

Please sign in to comment.