Skip to content

Bare except

bare_except

Bare except clause detection.

BareExceptRule dataclass

Bases: ProjectRule

Detect bare except clauses (except: without type).

Source code in packages/axm-audit/src/axm_audit/core/rules/practices/bare_except.py
Python
@dataclass
@register_rule("practices")
class BareExceptRule(ProjectRule):
    """Detect bare except clauses (except: without type)."""

    @property
    def rule_id(self) -> str:
        """Unique identifier for this rule."""
        return "PRACTICE_BARE_EXCEPT"

    def check(self, project_path: Path) -> CheckResult:
        """Check for bare except clauses in the project."""
        early = self.check_src(project_path)
        if early is not None:
            return early

        src_path = project_path / "src"
        bare_excepts = self._collect_bare_excepts(src_path)

        count = len(bare_excepts)
        passed = count == 0
        score = max(0, 100 - count * 20)

        text_lines = [
            f"     • {_short_path(str(loc['file']))}:{loc['line']}"
            for loc in bare_excepts
        ]

        return CheckResult(
            rule_id=self.rule_id,
            passed=passed,
            message=f"{count} bare except(s) found",
            severity=Severity.WARNING if not passed else Severity.INFO,
            score=int(score),
            details={
                "bare_except_count": count,
                "locations": bare_excepts,
            },
            text="\n".join(text_lines) if text_lines else None,
            fix_hint="Use specific exception types (e.g., except ValueError:)"
            if not passed
            else None,
        )

    def _collect_bare_excepts(
        self,
        src_path: Path,
    ) -> list[dict[str, str | int]]:
        """Parse every ``.py`` file under *src_path* and gather bare excepts."""
        bare_excepts: list[dict[str, str | int]] = []
        for path in get_python_files(src_path):
            cache = get_ast_cache()
            tree = cache.get_or_parse(path) if cache else parse_file_safe(path)
            if tree is None:
                continue
            self._find_bare_excepts(tree, path, src_path, bare_excepts)
        return bare_excepts

    def _find_bare_excepts(
        self,
        tree: ast.Module,
        path: Path,
        src_path: Path,
        bare_excepts: list[dict[str, str | int]],
    ) -> None:
        """Find bare except clauses in a syntax tree."""
        for node in ast.walk(tree):
            if isinstance(node, ast.ExceptHandler):
                if node.type is None:
                    bare_excepts.append(
                        {
                            "file": str(path.relative_to(src_path)),
                            "line": node.lineno,
                        }
                    )
rule_id property

Unique identifier for this rule.

check(project_path)

Check for bare except clauses in the project.

Source code in packages/axm-audit/src/axm_audit/core/rules/practices/bare_except.py
Python
def check(self, project_path: Path) -> CheckResult:
    """Check for bare except clauses in the project."""
    early = self.check_src(project_path)
    if early is not None:
        return early

    src_path = project_path / "src"
    bare_excepts = self._collect_bare_excepts(src_path)

    count = len(bare_excepts)
    passed = count == 0
    score = max(0, 100 - count * 20)

    text_lines = [
        f"     • {_short_path(str(loc['file']))}:{loc['line']}"
        for loc in bare_excepts
    ]

    return CheckResult(
        rule_id=self.rule_id,
        passed=passed,
        message=f"{count} bare except(s) found",
        severity=Severity.WARNING if not passed else Severity.INFO,
        score=int(score),
        details={
            "bare_except_count": count,
            "locations": bare_excepts,
        },
        text="\n".join(text_lines) if text_lines else None,
        fix_hint="Use specific exception types (e.g., except ValueError:)"
        if not passed
        else None,
    )