Repository navigation
Add B047: except handler shadowed by an earlier one - #589
Merged
cooperlees merged 3 commits intoOct 9, 2026
Merged
Conversation
A handler like `except ValueError:` placed after `except Exception:` can never run, since the earlier handler already catches every ValueError. The same goes for a bare `except:` after `except BaseException:`. Like B014, only builtin exceptions are checked, since we can't know the hierarchy of other classes from the AST. Catching the exact same name twice is still left to B025. Closes PyCQA#349
…cept-handlers # Conflicts: # README.rst # bugbear.py
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
B047 misses unreachable builtin exceptions inside valid starred handler tuples.
1 open finding
What changed in this PR
This PR adds B047 to flake8-bugbear to flag except and except* handlers shadowed by earlier handlers for builtin exceptions.
Changes:
- Add the B047 check and diagnostic message.
- Add examples and regression tests for ordinary and starred exception handlers.
- Document B047 in the README and unreleased changelog.
| File | Description |
|---|---|
| tests/eval_files/b047.py | Tests ordinary handler ordering. |
| tests/eval_files/b047_py311.py | Tests except* ordering. |
| README.rst | Documents B047 and its release note. |
| bugbear.py | Implements and registers B047. |
🧠 Review effort: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+2224
to
+2225
| elif isinstance(handler.type, ast.Tuple): | ||
| names = [e.id for e in handler.type.elts if isinstance(e, ast.Name)] |
Contributor
Author
There was a problem hiding this comment.
Good catch, B047 now collects names through _flatten_excepthandler, so starred tuple entries are expanded, and the except (*(ValueError,),): case is covered in b047.py.
cooperlees
approved these changes
Oct 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

B047 reports an
excepthandler that can never run because an earlier handler in the sametryalready catches a parent class:It also covers
except BaseException:followed byexcept Exception:or a bareexcept:, which was the first case in the issue. Works forexcept*too, and for names inside tuples.Like B014, it only looks at builtin exceptions since we can't know the hierarchy of other classes from the AST. Catching the exact same name twice is still left to B025.
B047 is the next free code after B045 and B046. Happy to renumber if needed.
Closes #349
Tested with
pytest tests/test_bugbear.py(3.10, 3.12, 3.13, 3.14),pre-commit run --all-files, and running it over the stdlib and site-packages with--select B047, which found nothing.