Skip to content

Commit d28ff32

Browse files
Fix crash on unusual except handlers (#370)
1 parent fc4dde8 commit d28ff32

File tree

3 files changed

+25
-8
lines changed

3 files changed

+25
-8
lines changed

README.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,11 @@ MIT
325325
Change Log
326326
----------
327327

328+
Unreleased
329+
~~~~~~~~~~
330+
331+
* B030: Fix crash on certain unusual except handlers (e.g. ``except a[0].b:``)
332+
328333
23.3.12
329334
~~~~~~~~
330335

bugbear.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -250,15 +250,18 @@ def _check_redundant_excepthandlers(names, node):
250250
def _to_name_str(node):
251251
# Turn Name and Attribute nodes to strings, e.g "ValueError" or
252252
# "pkg.mod.error", handling any depth of attribute accesses.
253+
# Return None for unrecognized nodes.
253254
if isinstance(node, ast.Name):
254255
return node.id
255256
if isinstance(node, ast.Call):
256257
return _to_name_str(node.func)
257-
assert isinstance(node, ast.Attribute), f"Unexpected node type: {type(node)}"
258-
try:
259-
return _to_name_str(node.value) + "." + node.attr
260-
except AttributeError:
261-
return _to_name_str(node.value)
258+
elif isinstance(node, ast.Attribute):
259+
inner = _to_name_str(node.value)
260+
if inner is None:
261+
return None
262+
return f"{inner}.{node.attr}"
263+
else:
264+
return None
262265

263266

264267
def names_from_assignments(assign_target):
@@ -345,19 +348,22 @@ def visit_ExceptHandler(self, node):
345348
self.generic_visit(node)
346349
return
347350
handlers = _flatten_excepthandler(node.type)
348-
good_handlers = []
351+
names = []
349352
bad_handlers = []
350353
ignored_handlers = []
351354
for handler in handlers:
352355
if isinstance(handler, (ast.Name, ast.Attribute)):
353-
good_handlers.append(handler)
356+
name = _to_name_str(handler)
357+
if name is None:
358+
ignored_handlers.append(handler)
359+
else:
360+
names.append(name)
354361
elif isinstance(handler, (ast.Call, ast.Starred)):
355362
ignored_handlers.append(handler)
356363
else:
357364
bad_handlers.append(handler)
358365
if bad_handlers:
359366
self.errors.append(B030(node.lineno, node.col_offset))
360-
names = [_to_name_str(e) for e in good_handlers]
361367
if len(names) == 0 and not bad_handlers and not ignored_handlers:
362368
self.errors.append(B029(node.lineno, node.col_offset))
363369
elif (

tests/b030.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,9 @@ def what_to_catch():
3232
pass
3333
except what_to_catch(): # ok
3434
pass
35+
36+
37+
try:
38+
pass
39+
except a.b[1].c: # ok
40+
pass

0 commit comments

Comments
 (0)