Enable `require-build-hashes` for the Python projects and inline scripts
so isolated builds require declared hashes for their build dependencies.
Pin the build backends and their dependencies with hashes.
---------
Co-authored-by: zaniebot <242828183+zaniebot@users.noreply.github.com>
## Summary
Enable `truthiness-test-of-none-union` in the standalone scripts' inline
configuration and in the `py-fuzzer` and `ty_benchmark` projects,
following #28889.
Summary
--
This PR updates our ruff-pre-commit dependency to 0.16.5, which supports
the new category selectors,
and then enables `lint.preview` and the new default categories so that
we can dogfood them on our
code. There were 66 diagnostics initially, which I also fixed or
ignored:
```
28 FURB113 [ ] repeated-append
12 ASYNC240 [ ] blocking-path-method-in-async-function
6 RUF105 [*] noqa-comments
5 PLW1510 [ ] subprocess-run-without-check
3 PLW0108 [ ] unnecessary-lambda
2 EXE001 [ ] shebang-not-executable
2 RUF039 [*] unraw-re-pattern
1 B024 [ ] abstract-base-class-without-abstract-method
1 FURB142 [*] for-loop-set-mutations
1 PERF102 [ ] incorrect-dict-iterator
1 PLC0207 [*] missing-maxsplit-arg
1 PLW0127 [ ] self-assigning-variable
1 TRY004 [ ] type-check-without-type-error
1 PLW0120 [*] useless-else-on-loop
1 TRY201 [ ] verbose-raise
```
Of these, I ignored `repeated-append` and `blocking-path-method-in-async-function`. I think they are
still reasonable defaults, just less useful/important in our uses.
0.16.5 also includes https://github.com/astral-sh/ruff-pre-commit/pull/159, so I removed `markdown` from our main `ruff-format` hook, leaving it for the later mdtest formatting stage.
I also had to make a few changes related to config discovery in tests:
- move our cached ecosystem checkouts to `$RUNNER_TEMP` instead of inside of our checkout
- convert some CLI tests to use the `CliTest` helpers
- add `configurationPreference: editorOnly` to some notebook tests
In these cases, our own Ruff settings were being inherited by test code. This likely affects many other tests, but I only updated the obviously failing ones for now. I'm least confident about the notebook tests, but as far as I can tell from the history (https://github.com/astral-sh/ruff/pull/11944, https://github.com/astral-sh/ruff/pull/22810), the specific diagnostics are not the important parts being asserted.
Test Plan
--
CI on this PR
Python tooling can currently build third-party source distributions. Set
`no-build` in the maintained Python projects and PEP 723 scripts,
retaining named exceptions for Git-pinned tooling and the local
ecosystem runner. Pin the isolated build dependencies for those
exceptions, including their transitive requirements.
Follows merged astral-sh/ruff#27856, which gives the legacy `ruff-lsp`
suite a dedicated, locked Python 3.12 test environment.
Follow-up to astral-sh/ruff#27843. Replaces astral-sh/ruff#27840, which
closed when the merged docs branch was deleted.
Co-authored-by: zaniebot <242828183+zaniebot@users.noreply.github.com>
<!--
Thank you for contributing to Ruff/ty! To help us out with reviewing,
please consider the following:
- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title? (Please prefix
with `[ty]` for ty pull
requests.)
- Does this pull request include references to any relevant issues?
- Does this PR follow our AI policy
(https://github.com/astral-sh/.github/blob/main/AI_POLICY.md)?
-->
## Summary
Adds explicit 7d cooldowns to all of our PEP 723 scripts, as well as
similar cooldowns via `.npmrc`.
<!-- What's the purpose of the change? What does it do, and why? -->
## Test Plan
NFC.
<!-- How was it tested? -->
---
<sub>Stack created with <a
href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a
href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub>
## Summary
- make the ecosystem-summary skill concise and output-focused, with an
explicit report template and separate subagent guidance
- capture the exact historical Ruff, ecosystem-analyzer, mypy-primer,
Python, and dependency-cutoff inputs from a GitHub Actions run
- move detailed minimization guidance into a reference and clarify how
primer projects must be reproduced
## Test plan
- `./scripts/collect_ty_ecosystem_run_metadata.py --help`
- validate both updated skills with `quick_validate.py`
- `uvx prek run --files <all changed files>`
## Summary
A bunch of followup changes from
https://github.com/astral-sh/ruff/pull/25422. Mostly triggered by using
the skill for the first time to analyze the report in
https://github.com/astral-sh/ruff/pull/24761.
- Move ty-specific guidance from `AGENTS.md` to a new local
`working-on-ty` skill. Link to the other ty-specific skills from that
skill.
- Add more keyword triggers to various skills so that agents are more
likely to automatically figure out that a skill is appropriate
(suggested by @dhruvmanila).
- Add more guidance to the ecosystem-minimization skill (and tweak the
script for setting up a primer project) so that agents are likely to
reproduce results in a deterministic and helpful way.
## Test Plan
I repeatedly ran `/review` with Codex on this until the only remaining
issues were trivial.
## Summary
This helps reduce spurious changes to the lockfile if you run these
scripts on a machine that has a global `exclude-newer` value set in a
`~/.config/uv.toml` file or similar. It also seems good more generally
to set an `exclude-newer` value for these scripts: dependency cooldowns
are better for security.
Note that if the machine, hypothetically, also set `UV_DEFAULT_INDEX` as
an environment variable to something other than `pypi.org/simple`, there
would still be changes to the lockfile, so this change may be necessary
but not sufficient for lockfile stability on _certain_ corporate
machines.
## Test Plan
I ensured that the `UV_DEFAULT_INDEX` environment variable was set to
`pypi.org/simple` on my machine and then ran `mdtest.py` using `uv run`.
I didn't run `setup_primer_project.py`, but I did lock it using `uv lock
--script`.
## Summary
Enable Ruff's own `S602` rule (`subprocess-popen-with-shell-equals-true`
from flake8-bandit) in `pyproject.toml` to enforce no-shell subprocess
calls going forward, and fix the two existing violations it catches.
**`pyproject.toml`** - adds `S602` to the lint `select` list so any
future `shell=True` usage in the scripts is caught automatically by the
linter.
**`scripts/setup_primer_project.py`** - `project.install_cmd` and
`project.deps` come from the mypy-primer project registry (an
externally-fetched third-party config). Both were joined into shell
strings and executed with `shell=True`, making them a supply-chain
injection vector. Fixed by tokenising with `shlex.split()` and dropping
`shell=True`.
**`scripts/ty_benchmark/src/benchmark/snapshot.py`** - `command.prepare`
was passed to `subprocess.run(..., shell=True)`. While no current caller
sets this field, it is a latent injection point. Fixed by tokenising
with `shlex.split()` and dropping `shell=True`; adds the missing `import
shlex`.
## Test Plan
Both scripts are developer-only utilities. The changes are semantically
equivalent for well-formed inputs - `shlex.split()` produces the same
argument list the shell would have constructed, while refusing to pass
metacharacters through to a shell process.
Verified no other `shell=True` uses remain in `scripts/` or `python/`
that would be newly flagged by S602.
## Summary
`uv run scripts/setup_primer_project.py <projname> <directory>` will
clone the mypy-primer project `<projname>` to `<directory>` and then
install it and its dependencies (in the way defined by mypy-primer) into
`.venv` in that directory, setting it up for easy reproduction of the
primer results.
Also added instructions to `CLAUDE.md` so Claude will use this script
when reproducing ecosystem results. This can short-circuit a lot of "it
doesn't reproduce! oh I didn't install the dependencies" churn.
## Test Plan
`uv run scripts/setup_primer_project.py artigraph /tmp/artigraph` set
things up such that I was able to just run two versions of ty in
`/tmp/artigraph` and quickly repro an ecosystem diff from CI.