Skip to content

Commit

Permalink
Fix crash on unusual except handlers (#370)
Browse files Browse the repository at this point in the history
  • Loading branch information
JelleZijlstra authored Mar 17, 2023
1 parent fc4dde8 commit d28ff32
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 8 deletions.
5 changes: 5 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,11 @@ MIT
Change Log
----------

Unreleased
~~~~~~~~~~

* B030: Fix crash on certain unusual except handlers (e.g. ``except a[0].b:``)

23.3.12
~~~~~~~~

Expand Down
22 changes: 14 additions & 8 deletions bugbear.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,15 +250,18 @@ def _check_redundant_excepthandlers(names, node):
def _to_name_str(node):
# Turn Name and Attribute nodes to strings, e.g "ValueError" or
# "pkg.mod.error", handling any depth of attribute accesses.
# Return None for unrecognized nodes.
if isinstance(node, ast.Name):
return node.id
if isinstance(node, ast.Call):
return _to_name_str(node.func)
assert isinstance(node, ast.Attribute), f"Unexpected node type: {type(node)}"
try:
return _to_name_str(node.value) + "." + node.attr
except AttributeError:
return _to_name_str(node.value)
elif isinstance(node, ast.Attribute):
inner = _to_name_str(node.value)
if inner is None:
return None
return f"{inner}.{node.attr}"
else:
return None


def names_from_assignments(assign_target):
Expand Down Expand Up @@ -345,19 +348,22 @@ def visit_ExceptHandler(self, node):
self.generic_visit(node)
return
handlers = _flatten_excepthandler(node.type)
good_handlers = []
names = []
bad_handlers = []
ignored_handlers = []
for handler in handlers:
if isinstance(handler, (ast.Name, ast.Attribute)):
good_handlers.append(handler)
name = _to_name_str(handler)
if name is None:
ignored_handlers.append(handler)
else:
names.append(name)
elif isinstance(handler, (ast.Call, ast.Starred)):
ignored_handlers.append(handler)
else:
bad_handlers.append(handler)
if bad_handlers:
self.errors.append(B030(node.lineno, node.col_offset))
names = [_to_name_str(e) for e in good_handlers]
if len(names) == 0 and not bad_handlers and not ignored_handlers:
self.errors.append(B029(node.lineno, node.col_offset))
elif (
Expand Down
6 changes: 6 additions & 0 deletions tests/b030.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,9 @@ def what_to_catch():
pass
except what_to_catch(): # ok
pass


try:
pass
except a.b[1].c: # ok
pass

0 comments on commit d28ff32

Please sign in to comment.