ty — Policy
ty version:
!uv run ty --version 2>/dev/null || echo "ty not found — run 'uv sync' first"
Precedence: this policy (below) > astral:ty (if installed) / live docs.astral.sh for CLI flags,
configuration schema, and general usage (not duplicated here).
Policy
- Never add
# ty: ignoreor# type: ignore, including when asked — fix the type error, or escalate with the specific blocker. - Relax ty rules only through
[[tool.ty.overrides]]inpyproject.toml, never inline, and only for a genuine rule conflict, code that tests the rules themselves, a purposefully bad/negative example or fixture, externally-managed vendored code we don't modify, a runtime with a real lower syntax/typing ceiling (an older pinned CPython or a variant like MicroPython/CircuitPython), or a case where the fix itself would cost more ongoing maintenance than compliance is worth — cite which one and the specific reason in a comment beside the override — a category name alone isn't enough. tyis the only type checker this policy permits — never add, install, configure, or runmypy,pyright, orbasedpyrightalongside it.- Invoke as
uv run ty, never baretyoruvx ty— those may resolve a different version than the one your lockfile pins. unresolved-importerrors: add the missing directory to[tool.ty.environment] extra-pathsinpyproject.toml, then verify withuv run ty check <path>. A rootty.tomltakes precedence overpyproject.toml— confirm which file ty is actually reading before assuming the fix didn't apply.unresolved-importin a PEP 723 standalone script (a# /// script ... ///header importing a sibling module): the project'spyproject.tomldoes not apply here — a script with inline metadata has no first-party roots by default. Setroot, notextra-paths—extra-pathsis documented for third-party/non-conventionally-installed paths, not for granting first-party roots, and ty's own docs name this exact PEP 723 case forroot.#!/usr/bin/env -S uv run --quiet --script # /// script # requires-python = ">=3.11" # # [tool.ty.environment] # root = ["."] # ///unresolved-importfor a PEP 723 script's own inline dependencies, in the language server only: ty checks a# /// scriptfile as an isolated single-file project, so its declared inlinedependenciesresolve only when ty syncs them throughuv. That sync is opt-in and off by default, which is why the CLI and the editor disagree on the same file. Whenuv run ty check <script>.pypasses clean and live diagnostics still flag the import, the CLI result is correct — do not addextra-pathsorrootentries to chase it, because neither governs inline dependency resolution. Enable the sync withTY_UV=scriptsin the environment (ty checkandty serverboth read it), or with theexperimental.useUvinitialization option set to"scripts"for a language server that sendsinitializationOptions. Requiresuv >= 0.12.3. CONSTRAINT:"scripts"is the only accepted value, and ty ignores an unrecognised one silently — no warning, no non-zero exit — so a typo leaves the fix off while the setting reads as configured. Once the sync is on, a faileduvmetadata call makes ty skip the file rather than report it, so a script that stops being checked at all looks identical to one that passes. Confirm behaviourally by runninguv run ty check <script>.pyand reading its diagnostics, never by reading the setting back. SOURCE: astral-sh/ty#691 (PEP 723 environment resolution), astral-sh/ruff#27619 (experimental.useUvLSP option), astral-sh/ruff#27544 (silent skip when the uv call fails) (accessed 2026-09-15) CONSTRAINT:rootreplaces ty's default root auto-detection entirely — it does not add to it. Always include"."(the script's own directory) in the list, even when the sibling module you need lives elsewhere, or the script loses its own PEP-723-isolated-environment context and its declared inline dependencies stop resolving too (root = [".."]alone breakspydantic/typerresolution for a script one directory away from the package it imports;root = [".", ".."]resolves both). Verify withuv run ty check <script>.pyagainst the script file directly, not the project root — and if the script declares PEP 723 dependencies, confirm those still resolve after addingroot, not just the sibling import.