|
| 1 | +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html |
| 2 | +# For details: https://github.com/pylint-dev/pylint/blob/main/LICENSE |
| 3 | +# Copyright (c) https://github.com/pylint-dev/pylint/blob/main/CONTRIBUTORS.txt |
| 4 | + |
| 5 | +"""Match statement checker for Python code.""" |
| 6 | + |
| 7 | +from __future__ import annotations |
| 8 | + |
| 9 | +from typing import TYPE_CHECKING |
| 10 | + |
| 11 | +from astroid import nodes |
| 12 | + |
| 13 | +from pylint.checkers import BaseChecker |
| 14 | +from pylint.checkers.utils import only_required_for_messages |
| 15 | +from pylint.interfaces import HIGH |
| 16 | + |
| 17 | +if TYPE_CHECKING: |
| 18 | + from pylint.lint import PyLinter |
| 19 | + |
| 20 | + |
| 21 | +class MatchStatementChecker(BaseChecker): |
| 22 | + name = "match_statements" |
| 23 | + msgs = { |
| 24 | + "E1901": ( |
| 25 | + "The name capture `case %s` makes the remaining patterns unreachable. " |
| 26 | + "Use a dotted name (for example an enum) to fix this.", |
| 27 | + "bare-name-capture-pattern", |
| 28 | + "Emitted when a name capture pattern is used in a match statement " |
| 29 | + "and there are case statements below it.", |
| 30 | + ) |
| 31 | + } |
| 32 | + |
| 33 | + @only_required_for_messages("bare-name-capture-pattern") |
| 34 | + def visit_match(self, node: nodes.Match) -> None: |
| 35 | + """Check if a name capture pattern prevents the other cases from being |
| 36 | + reached. |
| 37 | + """ |
| 38 | + for idx, case in enumerate(node.cases): |
| 39 | + match case.pattern: |
| 40 | + case nodes.MatchAs(pattern=None, name=nodes.AssignName()) if ( |
| 41 | + idx < len(node.cases) - 1 |
| 42 | + ): |
| 43 | + self.add_message( |
| 44 | + "bare-name-capture-pattern", |
| 45 | + node=case.pattern, |
| 46 | + args=case.pattern.name.name, |
| 47 | + confidence=HIGH, |
| 48 | + ) |
| 49 | + |
| 50 | + |
| 51 | +def register(linter: PyLinter) -> None: |
| 52 | + linter.register_checker(MatchStatementChecker(linter)) |
0 commit comments