Skip to content

Promote develop to main: Settle the Python Gate's Behavior-Changing Edge Cases - #1943

Merged
ptr727 merged 2 commits into
mainfrom
develop
Sep 27, 2026
Merged

ptr727 merged 2 commits into
mainfrom
develop

Conversation

@ptr727

@ptr727 ptr727 commented Sep 27, 2026

Copy link
Copy Markdown
Owner

Summary

Promotes develop to main, carrying #1942. That PR settles the behavior-changing edge cases in the Python directory gate, applying the maintainer's decision on each #1936 item:

  • Item 1: mypy on a declared pip directory follows the repo's config. It runs from .venv when installed there, and a python_version the loaded config pins is no longer overridden.
  • Item 2: a declared subdirectory with no type-checker config falls back to the root's and names itself as the target. A setup.cfg [mypy] section also counts.
  • Item 3: a lint-only unittest run that exits 5 explains the likely causes.
  • Item 5: the audit reports a caller it cannot read, a renamed or extra job calling validate-task.yml or a flow-mapping with:, rather than skipping or misreading it.
  • Item 6: the audit selftest covers malformed types at the caller level.
  • Item 7: the Python profiles document a pyproject.toml beside requirements*.txt as the build profile.

Item 4 stays as is, by decision.

Closes #1936

🤖 Generated with Claude Code

## Summary

This PR applies the maintainer's decisions on #1936, recorded in [this
comment](#1936 (comment)).

- **Item 1, mypy on a declared pip directory.** mypy runs from `.venv`
when it is installed there. Otherwise it runs under `uvx`, and
`--python-version` is dropped when the config mypy actually loads pins
`python_version`. The pin check reads that config's mypy section only,
and accepts the INI `:` form.
- **Item 2, where checker config is found.** A declared subdirectory
with no checker config uses the repository root's config and runs the
checker from the root, naming the directory as the target so the root
config's file selection cannot skip it. A `setup.cfg` `[mypy]` section
now counts as config.
- **Item 3, unittest exit 5.** When a lint-only `unittest` run exits 5
because it found no tests, the step says why: pytest-style functions,
files not named `test*.py`, or a nested directory with no `__init__.py`.
- **Item 4:** left as is, by decision.
- **Item 5, the audit's caller check.** A caller that invokes
`validate-task.yml` from a job other than `validate`, or passes a
flow-mapping `with:`, is now reported instead of skipped or misread.
- **Item 6, audit selftest.** Adds malformed-`types` cases for the
callers that had none.
- **Item 7, profile docs.** `python.profile.detect` and the
python-codestyle profiles now name a `pyproject.toml` beside a
`requirements*.txt` as the build profile.

The local strict review ran three rounds. The four real findings from
round 1 and the one from round 2 are fixed on this branch, and round 3
found nothing. One finding was already there before this change, and is
filed as #1941.

## Test plan

- `tests/test_release_guards.py`: runs the type-check step against stub
tools. It covers the venv mypy, a pinned or unpinned config, a pin in
the wrong section or in a file mypy does not load, the INI colon form,
`setup.cfg`, and the root fallback's target. It also covers the exit-5
message. Each new behavior was mutated and the mutant failed its test.
- `spec/audit.py --selftest` covers the renamed job, a second calling
job, the flow mapping, and malformed `types`. Each case was
mutation-checked.
- The full local gate block from OPERATIONS.md passes.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings September 27, 2026 23:35
@coderabbitai

coderabbitai Bot commented Sep 27, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Repository: ptr727/ProjectTemplate/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: a115a26d-ee2b-4668-84a5-badb24c65425


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Sep 27, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 12 lines in your changes missing coverage. Please review.
✅ Project coverage is 55.36%. Comparing base (9b594b9) to head (29a9690).
⚠️ Report is 287 commits behind head on main.

Files with missing lines Patch % Lines
spec/audit.py 0.00% 12 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1943      +/-   ##
==========================================
- Coverage   55.41%   55.36%   -0.06%     
==========================================
  Files          16       16              
  Lines        7209     7216       +7     
==========================================
  Hits         3995     3995              
- Misses       3214     3221       +7     
Flag Coverage Δ
python-3.13 55.36% <0.00%> (-0.06%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

The new audit DRIFT message for non-validate jobs is grammatically unclear when multiple jobs call validate-task.yml, which can confuse audit output interpretation.

Review effort: Lite
Findings: 1 Low severity

Open (1)
What changed in this PR

Promotes develop to main with the Python directory gate updates that clarify several edge-case behaviors (type-checker config discovery/fallbacks, mypy execution environment selection, and improved audit/selftest coverage), plus documentation/test updates to lock the behavior in.

Changes:

  • Update the reusable validate-task.yml workflow to (a) prefer venv-installed mypy when available, (b) avoid overriding a config-pinned python_version, (c) fall back to root type-checker config for declared subdirectories, and (d) explain unittest discovery exit-5 failures.
  • Extend spec/audit.py to report unreadable caller shapes (renamed/extra job keys calling validate-task.yml, flow-mapping with:) and add selftests for malformed types.
  • Update specs/docs and regression tests to reflect and validate the new Python gate behavior.
File Description
tests/​test_release_guards.py Expands regression coverage for the updated Python gate behavior (mypy environment selection, pinned python_version handling, root-config fallback, unittest exit-5 explanation).
spec/​project-types.json Updates the Python profile contract to treat pyproject.toml + requirements*.txt as build profile (pip-installed), even without [project].
spec/​audit.py Enhances caller auditing to report unreadable caller shapes and adds selftests for malformed types inputs.
docs/​reusable-workflows.md Documents root-config fallback behavior for type checking in declared subdirectories.
.github/​workflows/​validate-task.yml Implements the Python gate behavior changes (checker discovery, root fallback, venv mypy preference, pinned python_version handling, unittest exit-5 explanation).
.github/​skills/​python-codestyle/​references/​profiles.md Updates distributed skill docs to reflect the adjusted Python profile detection rules.
.claude-plugin/​fleet-skills/​skills/​python-codestyle/​references/​profiles.md Updates distributed plugin skill docs to reflect the adjusted Python profile detection rules.
.claude-plugin/​fleet-skills/​.source-digests/​python-codestyle Updates the source digest to match the python-codestyle skill changes.
.agents/​skills/​python-codestyle/​references/​profiles.md Updates the source skill docs to reflect the adjusted Python profile detection rules.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread spec/audit.py Outdated
## Summary

Fixes the grammar finding Copilot raised on promotion PR
[#1943](#1943). When
several non-`validate` jobs call validate-task.yml, the audit's DRIFT
message used singular wording ("from job a, b, whose ..."). It now says
"from job X" for one and "from jobs X, Y" for several, followed by "and
only the job keyed 'validate' has its python-directories input compared
against the registry."

## Test plan

- `spec/audit.py --selftest` passes.
- The message was printed for a two-job caller and reads correctly.
- A local strict review found nothing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings September 27, 2026 23:43

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

The workflow’s pins_python_version() selects pyproject.toml before setup.cfg, which can miss a python_version pin in setup.cfg when both exist and lead to an unintended --python-version override.

Review effort: Lite
Findings: None

Resolved since last review (1)
Previously missed (1)

In code that hasn't changed since last review

Medium severity Prefer setup.cfg over pyproject.toml for python version pinning

.github/​workflows/​validate-task.yml:322

pins_python_version() checks pyproject.toml before setup.cfg. In a directory that has both a [tool.mypy] section in pyproject.toml and a [mypy] section in setup.cfg, this will treat pyproject.toml as the authoritative config and may miss a python_version pinned in setup.cfg, causing the workflow to pass --python-version and potentially override the intended pin. Prefer setup.cfg over pyproject.toml here to match the "one config file" intent and avoid silently ignoring pins.

@ptr727

ptr727 commented Sep 27, 2026

Copy link
Copy Markdown
Owner Author

Prefer setup.cfg over pyproject.toml for python version pinning: pins_python_version() checks pyproject.toml before setup.cfg ... may miss a python_version pinned in setup.cfg

Declining: mypy itself loads pyproject.toml (when it holds [tool.mypy]) ahead of setup.cfg, so a pin found only in setup.cfg is one mypy never reads. Checking setup.cfg first would honor a pin mypy ignores. The step follows mypy's own lookup order: mypy.ini, .mypy.ini, pyproject.toml, setup.cfg. I confirmed this with mypy 2.3.1 on a constructed directory whose pyproject.toml has [tool.mypy] and whose setup.cfg has [mypy] python_version = 3.12:

$ uvx mypy@latest --verbose a.py 2>&1 | grep -i "config file"
LOG:  Config File:            <dir>/pyproject.toml

@ptr727
ptr727 merged commit 9040965 into main Sep 27, 2026
11 checks passed
ptr727 added a commit that referenced this pull request Sep 28, 2026
… and Setup Tooling (#2000)

## Summary

Promotes develop to main, carrying the 16 pull requests merged to
develop since #1943.

- **Wait-loop guard (requirement 7):**
[#1999](#1999) credits a
comparison bound only inside a `[`, `[[`, or `test` invocation, and
[#1996](#1996) reconciles
the requirement's README count and diagram with its hook.
- **Registry:**
[#1994](#1994) and
[#1976](#1976) record
Vantage-Config's line endings and description.
- **Scripts and tooling:**
- [#1988](#1988) and
[#1972](#1972) harden
`ruleset_id()`.
- [#1974](#1974) and
[#1949](#1949) fix
`pr_review.py` `reply --match` and `wait`.
- [#1969](#1969),
[#1964](#1964),
[#1954](#1954) and
[#1951](#1951) fix
host-setup tool shadowing, shims, hook ownership and dpkg ownership
checks.
- **Gates and audit:**
- [#1980](#1980) triages a
path collision.
- [#1967](#1967) and
[#1962](#1962) tighten
sha-pin and version-literal checks.
- [#1956](#1956) keeps a
folded `if:` visible to the interface audit.

Closes #1636
Closes #1639
Closes #1948
Closes #1971
Closes #1718
Closes #1934
Closes #1877
Closes #1880
Closes #1865
Closes #1889
Closes #1966
Closes #1906
Closes #1935
Closes #1901
Closes #1905
Closes #1866
Closes #1897

🤖 Generated with [Claude Code](https://claude.com/claude-code)
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.

Decide the Python Directory Gate's Behavior-Changing Edge Cases

2 participants