Skip to content

errors: AST linter check_error_codes (raise + registry enforcement)#105

Merged
AbdelStark merged 1 commit into
mainfrom
errors/ast-linter-error-codes
May 20, 2026
Merged

errors: AST linter check_error_codes (raise + registry enforcement)#105
AbdelStark merged 1 commit into
mainfrom
errors/ast-linter-error-codes

Conversation

@AbdelStark

Copy link
Copy Markdown
Owner

Re-opening with base=main since the original PR (#104) was closed when its base branch was deleted on merge of #103.

Problem

RFC-0012 §3.3 and RFC-0015 §3.4 require two AST checks at PR time:

  • raise_geno_lewm_errorraise X(...) in geno_lewm/ only raises GenoLeWMError subclasses.
  • registered_error_code — the raised class is one of the leaves listed in ERROR_CODES.

Solution

  • tools/lint/check_error_codes.py — parses geno_lewm/errors.py with ast to derive the legal class set (no runtime import dependency); walks targets; flags non-registered raises with GitHub-Actions-friendly diagnostics.
  • tests/lint/test_check_error_codes.py — 19 cases covering bare re-raise, Name/Attribute raises, builtin raises (parametrized over 6), raise … from, syntax errors, and the self-skip on errors.py.
  • .github/workflows/lint-errors.yml — standalone per-PR workflow; designed to fold into testing: implement GitHub Actions per-PR CI workflow #86's full CI when that lands.

Validation

$ python -m tools.lint.check_error_codes
$ echo $?
0

$ python -m pytest tests/lint/ tests/unit/ -q
144 passed in 0.09s

Caveats

  • The linter rejects raise GenoLeWMError(...) because the root class is not in ERROR_CODES. Intentional — RFC says leaf classes only.
  • Name-based whitelist (not type-resolved). False positives only on dynamic raises (raise cls(...)).

Closes #22

Adds tools/lint/check_error_codes.py implementing the two AST checks
required by RFC-0012 §3.3 and RFC-0015 §3.4:

- raise_geno_lewm_error: every ``raise X(...)`` in geno_lewm/ raises a
  registered GenoLeWMError subclass (or is a bare re-raise).
- registered_error_code: the raised class is one of the leaf classes
  listed in geno_lewm/errors.py::ERROR_CODES.

The linter parses geno_lewm/errors.py with the ast module to discover
the legal class set, so it has no runtime dependency on the package
being installable. Output is GitHub-Actions-friendly
file:line:col: error: [check_name] message.

Wired into a standalone .github/workflows/lint-errors.yml that runs
on PR. Will fold into the full per-PR CI workflow (#86) when that
lands.

Tests in tests/lint/test_check_error_codes.py cover:
- registry discovery against the real errors module
- bare re-raise (allowed)
- registered raises (Name and Attribute forms)
- builtin raises (flagged)
- unregistered class raises (flagged)
- raise-from (still inspects class)
- syntax errors (reported as violations)
- the errors module itself is skipped

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

errors: AST linter raise_geno_lewm_error and registered_error_code

1 participant