Skip to content

Record which rules run on Python, measured rather than read - #3

Merged
zmaril merged 1 commit into
mainfrom
python-rule-inventory
Aug 4, 2026
Merged

Record which rules run on Python, measured rather than read#3
zmaril merged 1 commit into
mainfrom
python-rule-inventory

Conversation

@zmaril

@zmaril zmaril commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

A notes-only change. Once a Python parser pack exists (entl#13), some rules work on Python for free, some are lit up by the pack, some correctly decline, and some are genuinely Rust-only. The brief called that inventory "a cheap deliverable in itself"; this is it, taken by running each rule rather than by reading applies_to.

Two corpora: 44 files of CPython's Lib (json, asyncio, argparse, dataclasses), and a file written to contain one trigger for every regex rule.

Work today, no further work — seven rules

file-size (3 findings), deep-nesting (71), emoji, stray-todo, no-comments, unknown-barrier, unused-marker.

The pack is not what turned these on — nothing was. entl-codebase has carried a Python LanguageProfile all along, which is why stray-todo already had a Python test before any of tonight's work.

unknown-barrier is listed as applies, not demonstrated: I did not produce a finding for it.

Lit up by the pack, and by nothing else — two rules

exact-clone (26 findings) and near-clone (11). Verified by running the same 44 files against a parser-paths directory holding only the rust pack:

without the python pack   ok — no findings in 44 file(s)
with it                   37 error(s) across 44 file(s)

These read the pack's [tokenization] lists, which is what makes those lists load-bearing rather than decorative. infact-duplication classifies only leaf nodes, so declaring Python's string — a parent of string_start/string_content/string_end — would have named a kind that exists and normalized nothing, and near-clone would have compared string contents as if they were code. Silently. The pack declares string_content for that reason.

Correctly decline — four rules

color, inline-font, inline-svg, motion are all RegexRules gated on a style facet Python does not have. A Python file containing "#ff8800", a font-family string, an inline <svg> and a transition: string produces zero findings.

Recorded explicitly so nobody "fixes" it: giving Python a style facet would make every hex string in every Python file a finding.

Genuinely Rust-only — four rules, each with what it would need

error-discard is the interesting one. It is fact-backed through infact-errors, whose entire vocabulary is a fallible return type, and Python spells failure with exceptions. It needs [error-handling] in the pack plus a queries/discards.scm naming Python's forms (except: pass, an except that only logs, an unawaited coroutine, contextlib.suppress). The pack deliberately ships neither yet — inventing values for a Result-shaped manifest before writing the forms would be guessing.

effect-barrier and effect-capability need an effect catalog and a call graph. library-opportunity needs behavior derivation; infact-python-normalize (infact#24) is the half of that which now exists.

A gap this turned up

analysis-incomplete exists to say "fact-backed analysis could not inspect a source file." Run over 44 Python files with no Python parser pack configured, it reported nothing, and straitjacket printed:

ok — no findings in 44 file(s)

which reads as a clean repository and is not one. The rule reports facts.diagnostics, and those are parse failures; a file with no parser at all is never selected and so never becomes a diagnostic. The one case that most needs saying — an entire language went unanalyzed — is the one it cannot say.

With the pack it works exactly as intended, and names the construct:

gap.py:1:1  [analysis-incomplete]  exact-clones
  line 1: the grammar cannot read `T =`

The notes record the cheapest fix (have infact-analysis emit a diagnostic for a file whose language resolves to no pack) and that this is not hypothetical: it was Python's state until today and is every un-onboarded language's state now.

No code changed; cargo fmt --all --check is clean.

🤖 Generated with Claude Code

https://claude.ai/code/session_01UBzKrVRq966CUheQEUCunT

Once a Python parser pack exists, some rules work on Python for free, some
are lit up by the pack, some correctly decline, and some are genuinely
Rust-only. This is that inventory, taken by RUNNING each rule against 44
files of CPython's Lib and against a file written to trigger every regex
rule -- not by reading `applies_to`.

Seven rules already worked and the pack had nothing to do with it:
file-size, deep-nesting, emoji, stray-todo, no-comments, unknown-barrier,
unused-marker. `entl-codebase` has carried a Python LanguageProfile all
along, which is why.

Two are lit up by the pack and by nothing else. Against a parser-paths
directory holding only the rust pack the same 44 files produce "ok -- no
findings"; with the python pack they produce 37. exact-clone and near-clone
read the pack's [tokenization] lists, which is what makes those lists
load-bearing rather than decorative.

Four correctly decline: color, inline-font, inline-svg and motion are gated
on a style facet Python does not have, and a Python file containing a hex
string, a font-family, an inline SVG and a transition produces nothing.
Recorded so nobody "fixes" it.

Four are Rust-only, each with what it would need. error-discard is the
interesting one: it is fact-backed through a vocabulary built entirely
around a fallible return type, and Python spells failure with exceptions.

Also records a gap this turned up. `analysis-incomplete` reports parse
diagnostics, and a file with no parser pack at all is never selected and so
never becomes one. Run over 44 Python files with no Python pack configured
it said nothing, and straitjacket printed "ok -- no findings in 44 file(s)".
The one case that most needs saying is the one it cannot say.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UBzKrVRq966CUheQEUCunT
@zmaril
zmaril merged commit bf00bce into main Aug 4, 2026
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.

1 participant