Skip to content

refactor(python)!: rename AnalysisError — named like an exception, but not one #614

Description

@dekobon

Current behavior

AnalysisError is a frozen #[pyclass] value type returned (not raised) by analyze_batch (big-code-analysis-py/src/batch.rs:114-138; stub _native.pyi:64). Its own docs say so explicitly: "Not a subclass of Exception."

Runtime consequence of the name:

try:
    ...
except bca.AnalysisError:   # looks plausible
    ...
# TypeError: catching classes that do not inherit from BaseException is not allowed

Why it's a problem

  • PEP 8 reserves the ...Error suffix for exception classes. Every Python reader's first inference from AnalysisError is "this is raisable" — and the language punishes that inference with a TypeError at the except site.
  • It name-collides with the raised family it deliberately is not part of (ParseError, UnsupportedLanguageError), making the bindings' own error taxonomy look inconsistent.
  • The returned-not-raised design itself is good (per-file failures in a batch should be data, not control flow — stub:43-53). Only the name misleads.

Proposed 2.0 design

Rename to AnalysisFailure (or FileFailure) at 2.0. The class shape, fields, and returned-not-raised semantics are unchanged — this contests only the suffix.

Confidence note: this is a proposal. The current design was locked by #542's stability write-up (STABILITY.md:840-845); this issue argues that write-up pinned the right semantics under the wrong name, and pre-publish is the cheapest possible moment to fix it.

Breaking?

Yes — class rename. (Note: the package is NOT yet on PyPI per STABILITY.md:801-806 — renames before first publish are cheap; still 2.0-gated because STABILITY pins the current names as "the contract the first stable publish locks in".)

Part of the 2.0 UX audit; rolls up to the 2.x breaking-change roadmap #505.

Resolution Plan

Decision settled (design audit, 2026-06-10)

Name chosen: AnalysisFailure. Minimal conceptual change — keeps the
"Analysis" tie, drops the misleading ...Error suffix that PEP 8 reserves for
raisable exceptions. The class shape, fields, and returned-not-raised semantics
are unchanged; this contests only the suffix.

Steps

  1. Rename the #[pyclass] in big-code-analysis-py/src/batch.rs:114-138 via
    #[pyclass(name = "AnalysisFailure", …)], and update all internal
    references.
  2. Update the hand-written _native.pyi stub (drift-gated, :64 + the
    doc block :43-53) and the facade re-export in
    python/big_code_analysis/__init__.py.
  3. Tests (big-code-analysis-py/tests/): update the batch tests; add a
    regression test asserting the class is NOT raisable

    issubclass(AnalysisFailure, BaseException) is False — so the value-type
    contract stays pinned under the new name (this is the invariant the old name
    violated in readers' minds).
  4. Gates: mypy --strict + pyright, maturin develop + pytest, stub-drift
    gate.
  5. CHANGELOG ## [Unreleased]: (breaking) entry, deferred to 2.0.
  6. STABILITY.md: amend the docs(stability): bring Python bindings & REST schema under the 2.0 stability contract #542 bindings-contract section (:840-845) to the
    new name. Package is not yet on PyPI (:801-806), so the rename is cheap now
    but pinned by the 2.0 contract.

Note

Keep the raised error family (ParseError, UnsupportedLanguageError)
untouched — the rename's purpose is precisely to stop AnalysisFailure from
looking like a member of that family.

Assessment

Dimension Rating
Difficulty Low
Complexity Low
Priority Medium

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestlow-priorityLow-priority per issue-plan assessmentpythonPython language support / metricsuxUser-experience finding (2.0 UX audit)

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions