Skip to content

docs(stability): bring Python bindings & REST schema under the 2.0 stability contract #542

@dekobon

Description

@dekobon

Decided (2026-06-05): expose enum.StrEnum for languages/metrics (codegen from the LANG table; Lang.CPP == "cpp"); align analyze_batch to skip_generated=True + expose the 3 kwargs; lock Python dist/import/module names in STABILITY.md before first PyPI publish. See the resolved-decisions comment.

Summary

STABILITY.md and the #505 roadmap describe the Rust library contract and the
CLI artifact formats, but the Python bindings (big-code-analysis-py) and the
REST schema (big-code-analysis-web) are absent from the written stability
contract. Both are published surfaces; for a long-term 2.x they need an explicit
contract, especially the Python names, which cannot change after the first PyPI
publish.

Decisions to record (mostly documentation, one default)

  1. Lock the Python distribution/import names (big-code-analysis dist /
    big_code_analysis import / big_code_analysis._native compiled module —
    big-code-analysis-py/pyproject.toml). The import name cannot change
    post-publish without breaking every consumer. README still says "not yet
    published on PyPI" (big-code-analysis-py/README.md) — update before publish.

  2. Document the string-enum decision as intentional. supported_languages()
    list[str], METRIC_NAMEStuple[str, ...], AnalysisError.error_kind
    Literal[...] (big-code-analysis-py/src/lib.rs, _native.pyi). This is
    a deliberate, good design (strings round-trip with the CLI JSON
    language/metric vocabulary; Literal gives static-checker safety without a
    runtime enum). Record it as a 2.0 stability decision rather than converting
    to enum.Enum.

  3. analyze_batch default polarity (the one breaking item).
    analyze_batch hardcodes skip_generated=False
    (big-code-analysis-py/src/batch.rs:363), the inverse of analyze's True.
    Migrating a comprehension from analyze to analyze_batch silently changes
    generated-file handling. Decide at 2.0 whether the default should align with
    analyze. Exposing the three hardcoded kwargs
    (exclude_tests/allow_lossy_path/skip_generated) is additive and can land
    anytime.

Why 2.0-worthy

The name-locking and contract-documentation must precede the first stable Python
publish; the skip_generated default is breaking. The Python surface is
otherwise 2.0-ready (excellent error mapping, PEP 561 stubs, mypy --strict +
pyright gated).

Acceptance

Part of the pre-2.0 review (#505).

Resolution

Implemented on fix/issue-542 (commit 3220e2a). All three resolved
decisions landed:

  1. StrEnum Lang / MetricName (big_code_analysis._enums),
    generated from the live LANG::name() slugs (fix(web): /metrics language field emits non-lookup display names (c/c++, c#) #540) and
    Metric::NAMES by big-code-analysis-py/src/codegen.rs with a
    cargo test drift gate. Lang.CPP == "cpp";
    supported_languages() -> list[Lang],
    METRIC_NAMES -> tuple[MetricName, ...] (typed in the package
    facade; the _native FFI stays plain str). error_kind kept as
    a Literal. (Generator lives in the bindings crate, not enums/,
    because enums/ cannot see the fix(web): /metrics language field emits non-lookup display names (c/c++, c#) #540 slugs — see the resolution
    comment for the rationale.)
  2. analyze_batch skip_generated default flipped False -> True
    to align with analyze (breaking); exclude_tests /
    allow_lossy_path / skip_generated exposed as kwargs (additive).
  3. STABILITY.md gained Python-bindings (name lock, StrEnum
    contract, error mapping, PEP 561) and REST-schema (fix(web): /metrics language field emits non-lookup display names (c/c++, c#) #540/refactor(web): consistent error schema, response envelope, and introspection endpoints #541 /v1
    shape) sections, plus 2.0-horizon entries; README + book updated.

All cargo + Python gates (ruff / mypy --strict / pyright / maturin +
pytest) pass. Breaking: default flip + typed returns; additive:
StrEnums, kwargs, docs. Left open for review/merge — not closing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentation

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions