Skip to content

refactor: the Python code passes its own linter in strict mode - #14

Merged
JoshuaWink merged 1 commit into
betafrom
resolve-plain-logic
Oct 13, 2026
Merged

JoshuaWink merged 1 commit into
betafrom
resolve-plain-logic

Conversation

@JoshuaWink

Copy link
Copy Markdown
Member

What

The Python code of this repository had 120 warnings from its own rule CUP-I008 (logic that is not in a primitive). This change resolves all of them, and CI now runs the invariant linter with --strict.

How each one was resolved

52 in the code itself

  • 39 helper functions of the compiler Filters and of one lint Filter were functions at the top of their file. They are now static methods of the Filter that uses them. The logic is in the primitive.
  • 7 private helpers of three syntax-tree visitors and one Hook are now methods of their class.
  • The export pipeline was a function that built a Pipeline. It is now a named Pipeline, ExportPipeline. build_export_pipeline_v2 stays, and returns one.
  • Three small decisions became tables: the severity of a rule, the prefix of a report line, and the fix text of a rule.
  • The two lint_paths functions always put exclude, disable and strict in the first Payload. Before, each was added by an if.

68 with a comment that gives the reason

These are plain by design, and each has # cup: allow-plain <reason>:

What Count Reason
The primitives themselves (Payload, Pipeline, label_of) 3 The framework makes the primitives, so it is not written with them
Syntax-tree visitors 6 The tool that a Filter uses to read or change source code
Entries of programs, and what they use 6 They read arguments and print the result
The config reader 3 It runs before any pipeline exists
Shared helpers and records of the linter and compiler 6 Used by more than one Filter, or a record of data
The conformance runner 15 Test harness
The differential test harness (scorecard/) 29 Test harness

13 more comments are on conformance/run.py and conformance/bench.py (the judge and the speed check). They are not in the lint paths of cup.config.json, but the repository self-check covers them.

What keeps it this way

  • CI: python -m codeupipe_lint.invariants --strict. A new warning fails the run.
  • tests/lint/invariants/test_repo_is_clean.py now expects no finding and no warning. It also pins the number of allow-plain comments (81). A new comment changes that number, so a reviewer sees it.
  • CUP-I009 reports a comment that allows nothing, so an old one cannot stay.

Checks

  • Python tests: 521 pass, on Python 3.12 and 3.14.
  • Conformance: 30 of 30 on each target, nothing unsupported.
  • Speed check (Python 3.12): every number is within 25% of its baseline.
  • Both linters report nothing, in strict mode.

Not in this change

  • The TypeScript packages have 40 CUP-I008 warnings of their own. They are not touched here.

🤖 Generated with Claude Code

The 120 CUP-I008 warnings are resolved.

52 in the code itself: the helper functions of the compiler Filters and
of three visitors are now methods of their class, the export pipeline is
a named Pipeline, and three small decisions are tables.

68 with a comment that gives the reason, on code that is plain by
design: a primitive itself, a visitor of a syntax tree, the entry of a
program, a test harness. 13 more comments are on the conformance judge
and speed check, which the repository self-check also covers.

CI runs the invariant linter with --strict. The self-check test pins the
number of comments, so a new one is a change that someone sees.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@JoshuaWink
JoshuaWink added this pull request to stack #17 October 13, 2026 18:59
@JoshuaWink
JoshuaWink merged commit 75a9c8e into beta Oct 13, 2026
9 of 10 checks passed
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