```
├── .editorconfig (omitted)
├── .gitattributes (omitted)
├── .github/
├── ISSUE_TEMPLATE/
├── 1_bug_report.yaml (300 tokens)
├── 2_question.yaml (100 tokens)
├── config.yml (100 tokens)
├── PULL_REQUEST_TEMPLATE.md (100 tokens)
├── actionlint.yaml (100 tokens)
├── renovate.json5 (400 tokens)
├── workflows/
├── build-binaries.yml (3.5k tokens)
├── build-docker.yml (2.7k tokens)
├── ci.yaml (900 tokens)
├── daily_property_tests.yml (500 tokens)
├── publish-docs.yml (1000 tokens)
├── publish-pypi.yml (200 tokens)
├── release.yml (2.3k tokens)
├── .gitignore
├── .gitmodules
├── .markdownlint.yaml (100 tokens)
├── .pre-commit-config.yaml (600 tokens)
├── .python-version
├── CHANGELOG.md (19.2k tokens)
├── CODE_OF_CONDUCT.md (1100 tokens)
├── CONTRIBUTING.md (1300 tokens)
├── Dockerfile (300 tokens)
├── LICENSE (omitted)
├── README.md (600 tokens)
├── SECURITY.md (100 tokens)
├── _typos.toml
├── assets/
├── badge/
├── v0.json (100 tokens)
├── dist-workspace.toml (600 tokens)
├── docs/
├── .overrides/
├── main.html (300 tokens)
├── partials/
├── integrations/
├── analytics/
├── fathom.html
├── assets/
├── favicon.ico
├── logo-letter.svg (100 tokens)
├── configuration.md (400 tokens)
├── editors.md (400 tokens)
├── exclusions.md (600 tokens)
├── index.md (300 tokens)
├── installation.md (100 tokens)
├── js/
├── extra.js (500 tokens)
├── modules.md (500 tokens)
├── python-version.md (400 tokens)
├── reference/
├── cli.md (2k tokens)
├── configuration.md (2.7k tokens)
├── editor-settings.md (2.2k tokens)
├── environment.md (400 tokens)
├── exit-codes.md (200 tokens)
├── rules.md (15.8k tokens)
├── requirements-insiders.in
├── requirements-insiders.txt (700 tokens)
├── requirements.in
├── requirements.txt (700 tokens)
├── rules.md (300 tokens)
├── stylesheets/
├── extra.css (1400 tokens)
├── suppression.md (500 tokens)
├── mkdocs.insiders.yml
├── mkdocs.public.yml
├── mkdocs.template.yml (600 tokens)
├── pyproject.toml (700 tokens)
├── python/
├── ty/
├── __init__.py
├── __main__.py (600 tokens)
├── py.typed
├── scripts/
├── autogenerate_files.sh (100 tokens)
├── release.sh (200 tokens)
├── transform_readme.py (300 tokens)
├── update_schemastore.py (1200 tokens)
├── uv.lock (omitted)
```
## /.github/ISSUE_TEMPLATE/1_bug_report.yaml
```yaml path="/.github/ISSUE_TEMPLATE/1_bug_report.yaml"
name: Bug report
description: Report an error or unexpected behavior
body:
- type: markdown
attributes:
value: |
Thank you for taking the time to report an issue! We're glad to have you involved with ty.
**Before reporting, please make sure to search through [existing issues](https://github.com/astral-sh/ty/issues?q=is:issue+is:open+label:bug) (including [closed](https://github.com/astral-sh/ty/issues?q=is:issue%20state:closed%20label:bug)).**<br>
**In particular, check out the list of [frequently encountered problems](https://github.com/astral-sh/ty/issues/445).**
- type: textarea
attributes:
label: Summary
description: |
A clear and concise description of the bug, including a minimal reproducible example.
Be sure to include the command you invoked (e.g., `ty check`) and
the current ty settings (e.g., relevant sections from your `pyproject.toml`).
If possible, try to include the [playground](https://play.ty.dev) link that reproduces this issue.
validations:
required: true
- type: input
attributes:
label: Version
description: What version of ty are you using? (see `ty version`)
placeholder: e.g., ty 0.0.1 (ff9000864 2025-05-06)
validations:
required: false
```
## /.github/ISSUE_TEMPLATE/2_question.yaml
```yaml path="/.github/ISSUE_TEMPLATE/2_question.yaml"
name: Question
description: Ask a question about ty
labels: ["question"]
body:
- type: textarea
attributes:
label: Question
description: Describe your question in detail.
validations:
required: true
- type: input
attributes:
label: Version
description: What version of ty are you using? (see `ty version`)
placeholder: e.g., ty 0.0.1 (ff9000864 2025-05-06)
validations:
required: false
```
## /.github/ISSUE_TEMPLATE/config.yml
```yml path="/.github/ISSUE_TEMPLATE/config.yml"
blank_issues_enabled: true
contact_links:
- name: Documentation
url: https://github.com/astral-sh/ty/blob/main/README.md
about: Please consult the documentation before creating an issue.
- name: Community
url: https://discord.com/invite/astral-sh
about: Join our Discord community to ask questions and collaborate.
```
## /.github/PULL_REQUEST_TEMPLATE.md
<!--
Thank you for contributing to 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?
- Does this pull request include references to any relevant issues?
-->
## Summary
<!-- What's the purpose of the change? What does it do, and why? -->
## Test Plan
<!-- How was it tested? -->
## /.github/actionlint.yaml
```yaml path="/.github/actionlint.yaml"
# Configuration for the actionlint tool, which we run via pre-commit
# to verify the correctness of the syntax in our GitHub Actions workflows.
self-hosted-runner:
# Various runners we use that aren't recognized out-of-the-box by actionlint:
labels:
- depot-ubuntu-latest-8
- depot-ubuntu-22.04-16
- depot-ubuntu-22.04-32
- github-windows-2025-x86_64-8
- github-windows-2025-x86_64-16
```
## /.github/renovate.json5
```json5 path="/.github/renovate.json5"
{
$schema: "https://docs.renovatebot.com/renovate-schema.json",
dependencyDashboard: true,
suppressNotifications: ["prEditedNotification"],
extends: ["config:recommended"],
labels: ["internal"],
schedule: ["before 4am on Monday"],
semanticCommits: "disabled",
separateMajorMinor: false,
prHourlyLimit: 10,
enabledManagers: ["github-actions", "pre-commit"],
"pre-commit": {
enabled: true,
},
packageRules: [
// Pin GitHub Actions to immutable SHAs.
{
matchDepTypes: ["action"],
pinDigests: true,
},
// Annotate GitHub Actions SHAs with a SemVer version.
{
extends: ["helpers:pinGitHubActionDigests"],
extractVersion: "^(?<version>v?\\d+\\.\\d+\\.\\d+){{contextString}}quot;,
versioning: "regex:^v?(?<major>\\d+)(\\.(?<minor>\\d+)\\.(?<patch>\\d+))?{{contextString}}quot;,
},
{
// Group upload/download artifact updates, the versions are dependent
groupName: "Artifact GitHub Actions dependencies",
matchManagers: ["github-actions"],
matchDatasources: ["gitea-tags", "github-tags"],
matchPackageNames: ["actions/.*-artifact"],
description: "Weekly update of artifact-related GitHub Actions dependencies",
},
{
// This package rule disables updates for GitHub runners:
// we'd only pin them to a specific version
// if there was a deliberate reason to do so
groupName: "GitHub runners",
matchManagers: ["github-actions"],
matchDatasources: ["github-runners"],
description: "Disable PRs updating GitHub runners (e.g. 'runs-on: macos-14')",
enabled: false,
},
{
groupName: "pre-commit dependencies",
matchManagers: ["pre-commit"],
description: "Weekly update of pre-commit dependencies",
}
],
vulnerabilityAlerts: {
commitMessageSuffix: "",
labels: ["internal", "security"],
},
}
```
## /.github/workflows/build-binaries.yml
```yml path="/.github/workflows/build-binaries.yml"
# Build ty on all platforms.
#
# Generates both wheels (for PyPI) and archived binaries (for GitHub releases).
#
# Assumed to run as a subworkflow of .github/workflows/release.yml; specifically, as a local
# artifacts job within `cargo-dist`.
name: "Build binaries"
on:
workflow_call:
inputs:
plan:
required: true
type: string
pull_request:
paths:
# When we change pyproject.toml, we want to ensure that the maturin builds still work.
- pyproject.toml
# And when we change this workflow itself...
- .github/workflows/build-binaries.yml
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
env:
PACKAGE_NAME: ty
MODULE_NAME: ty
PYTHON_VERSION: "3.13"
CARGO_INCREMENTAL: 0
CARGO_NET_RETRY: 10
CARGO_TERM_COLOR: always
RUSTUP_MAX_RETRIES: 10
jobs:
sdist:
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-build') }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
persist-credentials: false
- uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: "Prep README.md"
run: python scripts/transform_readme.py
- name: "Build sdist"
uses: PyO3/maturin-action@86b9d133d34bc1b40018696f782949dac11bd380 # v1.49.4
with:
command: sdist
args: --out dist
- name: "Test sdist"
run: |
pip install dist/"${PACKAGE_NAME}"-*.tar.gz --force-reinstall
"${MODULE_NAME}" version
"${MODULE_NAME}" --help
python -m "${MODULE_NAME}" --help
- name: "Upload sdist"
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with:
name: wheels-sdist
path: dist
macos-x86_64:
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-build') }}
runs-on: macos-14
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
persist-credentials: false
- uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: ${{ env.PYTHON_VERSION }}
architecture: x64
- name: "Prep README.md"
run: python scripts/transform_readme.py
- name: "Build wheels - x86_64"
uses: PyO3/maturin-action@86b9d133d34bc1b40018696f782949dac11bd380 # v1.49.4
with:
target: x86_64
args: --release --locked --out dist
- name: "Upload wheels"
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with:
name: wheels-macos-x86_64
path: dist
- name: "Archive binary"
run: |
TARGET=x86_64-apple-darwin
ARCHIVE_NAME=ty-$TARGET
ARCHIVE_FILE=$ARCHIVE_NAME.tar.gz
mkdir -p $ARCHIVE_NAME
cp ruff/target/$TARGET/release/ty $ARCHIVE_NAME/ty
tar czvf $ARCHIVE_FILE $ARCHIVE_NAME
shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
- name: "Upload binary"
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with:
name: artifacts-macos-x86_64
path: |
*.tar.gz
*.sha256
macos-aarch64:
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-build') }}
runs-on: macos-14
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
persist-credentials: false
- uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: ${{ env.PYTHON_VERSION }}
architecture: arm64
- name: "Prep README.md"
run: python scripts/transform_readme.py
- name: "Build wheels - aarch64"
uses: PyO3/maturin-action@86b9d133d34bc1b40018696f782949dac11bd380 # v1.49.4
with:
target: aarch64
args: --release --locked --out dist
- name: "Test wheel - aarch64"
run: |
pip install dist/"${PACKAGE_NAME}"-*.whl --force-reinstall
ty --help
python -m ty --help
- name: "Upload wheels"
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with:
name: wheels-aarch64-apple-darwin
path: dist
- name: "Archive binary"
run: |
TARGET=aarch64-apple-darwin
ARCHIVE_NAME=ty-$TARGET
ARCHIVE_FILE=$ARCHIVE_NAME.tar.gz
mkdir -p $ARCHIVE_NAME
cp ruff/target/$TARGET/release/ty $ARCHIVE_NAME/ty
tar czvf $ARCHIVE_FILE $ARCHIVE_NAME
shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
- name: "Upload binary"
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with:
name: artifacts-aarch64-apple-darwin
path: |
*.tar.gz
*.sha256
windows:
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-build') }}
runs-on: windows-latest
strategy:
matrix:
platform:
- target: x86_64-pc-windows-msvc
arch: x64
- target: i686-pc-windows-msvc
arch: x86
- target: aarch64-pc-windows-msvc
arch: x64
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
persist-credentials: false
- uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: ${{ env.PYTHON_VERSION }}
architecture: ${{ matrix.platform.arch }}
- name: "Prep README.md"
run: python scripts/transform_readme.py
- name: "Build wheels"
uses: PyO3/maturin-action@86b9d133d34bc1b40018696f782949dac11bd380 # v1.49.4
with:
target: ${{ matrix.platform.target }}
args: --release --locked --out dist
env:
# aarch64 build fails, see https://github.com/PyO3/maturin/issues/2110
XWIN_VERSION: 16
- name: "Test wheel"
if: ${{ !startsWith(matrix.platform.target, 'aarch64') }}
shell: bash
run: |
python -m pip install dist/"${PACKAGE_NAME}"-*.whl --force-reinstall
"${MODULE_NAME}" version
"${MODULE_NAME}" --help
python -m "${MODULE_NAME}" --help
- name: "Upload wheels"
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with:
name: wheels-${{ matrix.platform.target }}
path: dist
- name: "Archive binary"
shell: bash
run: |
ARCHIVE_FILE=ty-${{ matrix.platform.target }}.zip
7z a $ARCHIVE_FILE ./ruff/target/${{ matrix.platform.target }}/release/ty.exe
sha256sum $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
- name: "Upload binary"
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with:
name: artifacts-${{ matrix.platform.target }}
path: |
*.zip
*.sha256
linux:
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-build') }}
runs-on: ubuntu-latest
strategy:
matrix:
target:
- x86_64-unknown-linux-gnu
- i686-unknown-linux-gnu
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
persist-credentials: false
- uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: ${{ env.PYTHON_VERSION }}
architecture: x64
- name: "Prep README.md"
run: python scripts/transform_readme.py
- name: "Build wheels"
uses: PyO3/maturin-action@86b9d133d34bc1b40018696f782949dac11bd380 # v1.49.4
with:
target: ${{ matrix.target }}
manylinux: auto
args: --release --locked --out dist
- name: "Test wheel"
if: ${{ startsWith(matrix.target, 'x86_64') }}
run: |
pip install dist/"${PACKAGE_NAME}"-*.whl --force-reinstall
"${MODULE_NAME}" version
"${MODULE_NAME}" --help
python -m "${MODULE_NAME}" --help
- name: "Upload wheels"
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with:
name: wheels-${{ matrix.target }}
path: dist
- name: "Archive binary"
shell: bash
run: |
set -euo pipefail
TARGET=${{ matrix.target }}
ARCHIVE_NAME=ty-$TARGET
ARCHIVE_FILE=$ARCHIVE_NAME.tar.gz
mkdir -p $ARCHIVE_NAME
cp ruff/target/$TARGET/release/ty $ARCHIVE_NAME/ty
tar czvf $ARCHIVE_FILE $ARCHIVE_NAME
shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
- name: "Upload binary"
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with:
name: artifacts-${{ matrix.target }}
path: |
*.tar.gz
*.sha256
linux-cross:
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-build') }}
runs-on: ubuntu-latest
strategy:
matrix:
platform:
- target: aarch64-unknown-linux-gnu
arch: aarch64
# see https://github.com/astral-sh/ruff/issues/3791
# and https://github.com/gnzlbg/jemallocator/issues/170#issuecomment-1503228963
maturin_docker_options: -e JEMALLOC_SYS_WITH_LG_PAGE=16
- target: armv7-unknown-linux-gnueabihf
arch: armv7
- target: s390x-unknown-linux-gnu
arch: s390x
- target: powerpc64le-unknown-linux-gnu
arch: ppc64le
# see https://github.com/astral-sh/ruff/issues/10073
maturin_docker_options: -e JEMALLOC_SYS_WITH_LG_PAGE=16
- target: powerpc64-unknown-linux-gnu
arch: ppc64
# see https://github.com/astral-sh/ruff/issues/10073
maturin_docker_options: -e JEMALLOC_SYS_WITH_LG_PAGE=16
- target: arm-unknown-linux-musleabihf
arch: arm
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
persist-credentials: false
- uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: "Prep README.md"
run: python scripts/transform_readme.py
- name: "Build wheels"
uses: PyO3/maturin-action@86b9d133d34bc1b40018696f782949dac11bd380 # v1.49.4
with:
target: ${{ matrix.platform.target }}
manylinux: auto
docker-options: ${{ matrix.platform.maturin_docker_options }}
args: --release --locked --out dist
- uses: uraimo/run-on-arch-action@d94c13912ea685de38fccc1109385b83fd79427d # v3.0.1
if: ${{ matrix.platform.arch != 'ppc64' && matrix.platform.arch != 'ppc64le'}}
name: Test wheel
with:
arch: ${{ matrix.platform.arch == 'arm' && 'armv6' || matrix.platform.arch }}
distro: ${{ matrix.platform.arch == 'arm' && 'bullseye' || 'ubuntu20.04' }}
githubToken: ${{ github.token }}
install: |
apt-get update
apt-get install -y --no-install-recommends python3 python3-pip
pip3 install -U pip
run: |
pip3 install ${{ env.PACKAGE_NAME }} --no-index --find-links dist/ --force-reinstall
ty --help
- name: "Upload wheels"
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with:
name: wheels-${{ matrix.platform.target }}
path: dist
- name: "Archive binary"
shell: bash
run: |
set -euo pipefail
TARGET=${{ matrix.platform.target }}
ARCHIVE_NAME=ty-$TARGET
ARCHIVE_FILE=$ARCHIVE_NAME.tar.gz
mkdir -p $ARCHIVE_NAME
cp ruff/target/$TARGET/release/ty $ARCHIVE_NAME/ty
tar czvf $ARCHIVE_FILE $ARCHIVE_NAME
shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
- name: "Upload binary"
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with:
name: artifacts-${{ matrix.platform.target }}
path: |
*.tar.gz
*.sha256
musllinux:
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-build') }}
runs-on: ubuntu-latest
strategy:
matrix:
target:
- x86_64-unknown-linux-musl
- i686-unknown-linux-musl
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
persist-credentials: false
- uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: ${{ env.PYTHON_VERSION }}
architecture: x64
- name: "Prep README.md"
run: python scripts/transform_readme.py
- name: "Build wheels"
uses: PyO3/maturin-action@86b9d133d34bc1b40018696f782949dac11bd380 # v1.49.4
with:
target: ${{ matrix.target }}
manylinux: musllinux_1_2
args: --release --locked --out dist
- name: "Test wheel"
if: matrix.target == 'x86_64-unknown-linux-musl'
uses: addnab/docker-run-action@4f65fabd2431ebc8d299f8e5a018d79a769ae185 # v3
with:
image: alpine:latest
options: -v ${{ github.workspace }}:/io -w /io
run: |
apk add python3
python -m venv .venv
.venv/bin/pip3 install ${{ env.PACKAGE_NAME }} --no-index --find-links dist/ --force-reinstall
.venv/bin/${{ env.MODULE_NAME }} --help
- name: "Upload wheels"
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with:
name: wheels-${{ matrix.target }}
path: dist
- name: "Archive binary"
shell: bash
run: |
set -euo pipefail
TARGET=${{ matrix.target }}
ARCHIVE_NAME=ty-$TARGET
ARCHIVE_FILE=$ARCHIVE_NAME.tar.gz
mkdir -p $ARCHIVE_NAME
cp ruff/target/$TARGET/release/ty $ARCHIVE_NAME/ty
tar czvf $ARCHIVE_FILE $ARCHIVE_NAME
shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
- name: "Upload binary"
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with:
name: artifacts-${{ matrix.target }}
path: |
*.tar.gz
*.sha256
musllinux-cross:
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-build') }}
runs-on: ubuntu-latest
strategy:
matrix:
platform:
- target: aarch64-unknown-linux-musl
arch: aarch64
maturin_docker_options: -e JEMALLOC_SYS_WITH_LG_PAGE=16
- target: armv7-unknown-linux-musleabihf
arch: armv7
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
persist-credentials: false
- uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: "Prep README.md"
run: python scripts/transform_readme.py
- name: "Build wheels"
uses: PyO3/maturin-action@86b9d133d34bc1b40018696f782949dac11bd380 # v1.49.4
with:
target: ${{ matrix.platform.target }}
manylinux: musllinux_1_2
args: --release --locked --out dist
docker-options: ${{ matrix.platform.maturin_docker_options }}
- uses: uraimo/run-on-arch-action@d94c13912ea685de38fccc1109385b83fd79427d # v3.0.1
name: Test wheel
with:
arch: ${{ matrix.platform.arch }}
distro: alpine_latest
githubToken: ${{ github.token }}
install: |
apk add python3
run: |
python -m venv .venv
.venv/bin/pip3 install ${{ env.PACKAGE_NAME }} --no-index --find-links dist/ --force-reinstall
.venv/bin/${{ env.MODULE_NAME }} --help
- name: "Upload wheels"
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with:
name: wheels-${{ matrix.platform.target }}
path: dist
- name: "Archive binary"
shell: bash
run: |
set -euo pipefail
TARGET=${{ matrix.platform.target }}
ARCHIVE_NAME=ty-$TARGET
ARCHIVE_FILE=$ARCHIVE_NAME.tar.gz
mkdir -p $ARCHIVE_NAME
cp ruff/target/$TARGET/release/ty $ARCHIVE_NAME/ty
tar czvf $ARCHIVE_FILE $ARCHIVE_NAME
shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
- name: "Upload binary"
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with:
name: artifacts-${{ matrix.platform.target }}
path: |
*.tar.gz
*.sha256
```
## /.github/workflows/build-docker.yml
```yml path="/.github/workflows/build-docker.yml"
# Build and publish a Docker image.
#
# Assumed to run as a subworkflow of .github/workflows/release.yml; specifically, as a local
# artifacts job within `cargo-dist`.
#
# TODO(charlie): Ideally, the publish step would happen as a publish job within `cargo-dist`, but
# sharing the built image as an artifact between jobs is challenging.
name: "Build Docker image"
on:
workflow_call:
inputs:
plan:
required: true
type: string
pull_request:
paths:
- .github/workflows/build-docker.yml
env:
TY_BASE_IMG: ghcr.io/${{ github.repository_owner }}/ty
permissions:
contents: read
# TODO(zanieb): Ideally, this would be `read` on dry-run but that will require
# significant changes to the workflow.
packages: write # zizmor: ignore[excessive-permissions]
jobs:
docker-build:
name: Build Docker image (ghcr.io/astral-sh/ty) for ${{ matrix.platform }}
runs-on: ubuntu-latest
environment:
name: release
strategy:
fail-fast: false
matrix:
platform:
- linux/amd64
- linux/arm64
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
persist-credentials: false
- uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
- uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Check tag consistency
if: ${{ inputs.plan != '' && !fromJson(inputs.plan).announcement_tag_is_implicit }}
env:
TAG: ${{ inputs.plan != '' && fromJson(inputs.plan).announcement_tag || 'dry-run' }}
run: |
version=$(grep -m 1 "^version = " dist-workspace.toml | sed -e 's/version = "\(.*\)"/\1/g')
if [ "${TAG}" != "${version}" ]; then
echo "The input tag does not match the version from dist-workspace.toml:" >&2
echo "${TAG}" >&2
echo "${version}" >&2
exit 1
else
echo "Releasing ${version}"
fi
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0
with:
images: ${{ env.TY_BASE_IMG }}
# Defining this makes sure the org.opencontainers.image.version OCI label becomes the actual release version and not the branch name
tags: |
type=raw,value=dry-run,enable=${{ inputs.plan == '' || fromJson(inputs.plan).announcement_tag_is_implicit }}
type=pep440,pattern={{ version }},value=${{ inputs.plan != '' && fromJson(inputs.plan).announcement_tag || 'dry-run' }},enable=${{ inputs.plan != '' && !fromJson(inputs.plan).announcement_tag_is_implicit }}
- name: Normalize Platform Pair (replace / with -)
run: |
platform=${{ matrix.platform }}
echo "PLATFORM_TUPLE=${platform//\//-}" >> "$GITHUB_ENV"
# Adapted from https://docs.docker.com/build/ci/github-actions/multi-platform/
- name: Build and push by digest
id: build
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
with:
context: .
platforms: ${{ matrix.platform }}
cache-from: type=gha,scope=ty-${{ env.PLATFORM_TUPLE }}
cache-to: type=gha,mode=min,scope=ty-${{ env.PLATFORM_TUPLE }}
labels: ${{ steps.meta.outputs.labels }}
outputs: type=image,name=${{ env.TY_BASE_IMG }},push-by-digest=true,name-canonical=true,push=${{ inputs.plan != '' && !fromJson(inputs.plan).announcement_tag_is_implicit }}
- name: Export digests
env:
digest: ${{ steps.build.outputs.digest }}
run: |
mkdir -p /tmp/digests
touch "/tmp/digests/${digest#sha256:}"
- name: Upload digests
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with:
name: digests-${{ env.PLATFORM_TUPLE }}
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1
docker-publish:
name: Publish Docker image (ghcr.io/astral-sh/ty)
runs-on: ubuntu-latest
environment:
name: release
needs:
- docker-build
if: ${{ inputs.plan != '' && !fromJson(inputs.plan).announcement_tag_is_implicit }}
steps:
- name: Download digests
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
with:
path: /tmp/digests
pattern: digests-*
merge-multiple: true
- uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0
with:
images: ${{ env.TY_BASE_IMG }}
# Order is on purpose such that the label org.opencontainers.image.version has the first pattern with the full version
tags: |
type=pep440,pattern={{ version }},value=${{ fromJson(inputs.plan).announcement_tag }}
type=raw,value=${{ fromJson(inputs.plan).announcement_tag }}
type=pep440,pattern={{ major }}.{{ minor }},value=${{ fromJson(inputs.plan).announcement_tag }}
- uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
# Adapted from https://docs.docker.com/build/ci/github-actions/multi-platform/
- name: Create manifest list and push
working-directory: /tmp/digests
# The jq command expands the docker/metadata json "tags" array entry to `-t tag1 -t tag2 ...` for each tag in the array
# The printf will expand the base image with the `<TY_BASE_IMG>@sha256:<sha256> ...` for each sha256 in the directory
# The final command becomes `docker buildx imagetools create -t tag1 -t tag2 ... <TY_BASE_IMG>@sha256:<sha256_1> <TY_BASE_IMG>@sha256:<sha256_2> ...`
run: |
# shellcheck disable=SC2046
docker buildx imagetools create \
$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf "${TY_BASE_IMG}@sha256:%s " *)
docker-publish-extra:
name: Publish additional Docker image based on ${{ matrix.image-mapping }}
runs-on: ubuntu-latest
environment:
name: release
needs:
- docker-publish
if: ${{ inputs.plan != '' && !fromJson(inputs.plan).announcement_tag_is_implicit }}
strategy:
fail-fast: false
matrix:
# Mapping of base image followed by a comma followed by one or more base tags (comma separated)
# Note, org.opencontainers.image.version label will use the first base tag (use the most specific tag first)
image-mapping:
- alpine:3.21,alpine3.21,alpine
- debian:bookworm-slim,bookworm-slim,debian-slim
- buildpack-deps:bookworm,bookworm,debian
steps:
- uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
- uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Generate Dynamic Dockerfile Tags
shell: bash
env:
TAG_VALUE: ${{ fromJson(inputs.plan).announcement_tag }}
run: |
set -euo pipefail
# Extract the image and tags from the matrix variable
IFS=',' read -r BASE_IMAGE BASE_TAGS <<< "${{ matrix.image-mapping }}"
# Generate Dockerfile content
cat <<EOF > Dockerfile
FROM ${BASE_IMAGE}
COPY --from=${TY_BASE_IMG}:${TAG_VALUE} /ty /usr/local/bin/ty
ENTRYPOINT []
CMD ["/usr/local/bin/ty"]
EOF
# Initialize a variable to store all tag docker metadata patterns
TAG_PATTERNS=""
# Loop through all base tags and append its docker metadata pattern to the list
# Order is on purpose such that the label org.opencontainers.image.version has the first pattern with the full version
IFS=','; for TAG in ${BASE_TAGS}; do
TAG_PATTERNS="${TAG_PATTERNS}type=pep440,pattern={{ version }},suffix=-${TAG},value=${TAG_VALUE}\n"
TAG_PATTERNS="${TAG_PATTERNS}type=pep440,pattern={{ major }}.{{ minor }},suffix=-${TAG},value=${TAG_VALUE}\n"
TAG_PATTERNS="${TAG_PATTERNS}type=raw,value=${TAG}\n"
done
# Remove the trailing newline from the pattern list
TAG_PATTERNS="${TAG_PATTERNS%\\n}"
# Export image cache name
echo "IMAGE_REF=${BASE_IMAGE//:/-}" >> "$GITHUB_ENV"
# Export tag patterns using the multiline env var syntax
{
echo "TAG_PATTERNS<<EOF"
echo -e "${TAG_PATTERNS}"
echo EOF
} >> "$GITHUB_ENV"
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0
# ghcr.io prefers index level annotations
env:
DOCKER_METADATA_ANNOTATIONS_LEVELS: index
with:
images: ${{ env.TY_BASE_IMG }}
flavor: |
latest=false
tags: |
${{ env.TAG_PATTERNS }}
- name: Build and push
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
with:
context: .
platforms: linux/amd64,linux/arm64
# We do not really need to cache here as the Dockerfile is tiny
#cache-from: type=gha,scope=ty-${{ env.IMAGE_REF }}
#cache-to: type=gha,mode=min,scope=ty-${{ env.IMAGE_REF }}
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
annotations: ${{ steps.meta.outputs.annotations }}
# This is effectively a duplicate of `docker-publish` to make https://github.com/astral-sh/ty/pkgs/container/ty
# show the ty base image first since GitHub always shows the last updated image digests
# This works by annotating the original digests (previously non-annotated) which triggers an update to ghcr.io
docker-republish:
name: Annotate Docker image (ghcr.io/astral-sh/ty)
runs-on: ubuntu-latest
environment:
name: release
needs:
- docker-publish-extra
if: ${{ inputs.plan != '' && !fromJson(inputs.plan).announcement_tag_is_implicit }}
steps:
- name: Download digests
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
with:
path: /tmp/digests
pattern: digests-*
merge-multiple: true
- uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0
env:
DOCKER_METADATA_ANNOTATIONS_LEVELS: index
with:
images: ${{ env.TY_BASE_IMG }}
# Order is on purpose such that the label org.opencontainers.image.version has the first pattern with the full version
tags: |
type=pep440,pattern={{ version }},value=${{ fromJson(inputs.plan).announcement_tag }}
type=raw,value=${{ fromJson(inputs.plan).announcement_tag }}
type=pep440,pattern={{ major }}.{{ minor }},value=${{ fromJson(inputs.plan).announcement_tag }}
- uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
# Adapted from https://docs.docker.com/build/ci/github-actions/multi-platform/
- name: Create manifest list and push
working-directory: /tmp/digests
# The readarray part is used to make sure the quoting and special characters are preserved on expansion (e.g. spaces)
# The jq command expands the docker/metadata json "tags" array entry to `-t tag1 -t tag2 ...` for each tag in the array
# The printf will expand the base image with the `<TY_BASE_IMG>@sha256:<sha256> ...` for each sha256 in the directory
# The final command becomes `docker buildx imagetools create -t tag1 -t tag2 ... <TY_BASE_IMG>@sha256:<sha256_1> <TY_BASE_IMG>@sha256:<sha256_2> ...`
run: |
readarray -t lines <<< "$DOCKER_METADATA_OUTPUT_ANNOTATIONS"; annotations=(); for line in "${lines[@]}"; do annotations+=(--annotation "$line"); done
# shellcheck disable=SC2046
docker buildx imagetools create \
"${annotations[@]}" \
$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf "${TY_BASE_IMG}@sha256:%s " *)
```
## /.github/workflows/ci.yaml
```yaml path="/.github/workflows/ci.yaml"
name: CI
permissions:
contents: read
on:
push:
branches: [main]
pull_request:
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref_name }}-${{ github.event.pull_request.number || github.sha }}
cancel-in-progress: true
env:
CARGO_INCREMENTAL: 0
CARGO_NET_RETRY: 10
CARGO_TERM_COLOR: always
RUSTUP_MAX_RETRIES: 10
PACKAGE_NAME: ty
jobs:
python-package:
name: "python package"
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
submodules: recursive
- uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: ${{ env.PYTHON_VERSION }}
architecture: x64
- uses: Swatinem/rust-cache@f13886b937689c021905a6b90929199931d60db1 # v2.8.1
- name: "Build wheels"
uses: PyO3/maturin-action@86b9d133d34bc1b40018696f782949dac11bd380 # v1.49.4
with:
args: --out dist
- name: "Test wheel"
run: |
pip install --force-reinstall --find-links dist "${PACKAGE_NAME}" --pre
ty --help
python -m ty --help
- name: "Remove wheels from cache"
run: rm -rf target/wheels
pre-commit:
name: "pre-commit"
runs-on: depot-ubuntu-22.04-16
timeout-minutes: 10
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
- uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 # v7.1.2
- name: "Cache pre-commit"
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: ~/.cache/pre-commit
key: pre-commit-${{ hashFiles('.pre-commit-config.yaml') }}
- name: "Run pre-commit"
run: |
echo '\`\`\`console' > "$GITHUB_STEP_SUMMARY"
# Enable color output for pre-commit and remove it for the summary
# Use --hook-stage=manual to enable slower pre-commit hooks that are skipped by default
SKIP=cargo-fmt,clippy,dev-generate-all uvx --python="${PYTHON_VERSION}" pre-commit run --all-files --show-diff-on-failure --color=always --hook-stage=manual | \
tee >(sed -E 's/\x1B\[([0-9]{1,2}(;[0-9]{1,2})*)?[mGK]//g' >> "$GITHUB_STEP_SUMMARY") >&1
exit_code="${PIPESTATUS[0]}"
echo '\`\`\`' >> "$GITHUB_STEP_SUMMARY"
exit "$exit_code"
generated-check:
name: "Check generated files unedited"
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
submodules: recursive
- uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 # v7.1.2
- name: "Run auto generation scripts"
run: |
./scripts/autogenerate_files.sh
- name: "Check for uncommitted changes"
run: |
if [[ -n "$(git status --porcelain)" ]]; then
echo "Error: Auto-generated files were manually edited."
echo "Files with changes:"
git status --porcelain
exit 1
fi
docs:
timeout-minutes: 10
name: "mkdocs"
runs-on: ubuntu-latest
env:
MKDOCS_INSIDERS_SSH_KEY_EXISTS: ${{ secrets.MKDOCS_INSIDERS_SSH_KEY != '' }}
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
fetch-depth: 0
persist-credentials: false
- uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 # v7.1.2
- uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
- name: "Add SSH key"
if: ${{ env.MKDOCS_INSIDERS_SSH_KEY_EXISTS == 'true' }}
uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1
with:
ssh-private-key: ${{ secrets.MKDOCS_INSIDERS_SSH_KEY }}
- name: "Build docs (public)"
run: uvx --with-requirements docs/requirements.txt mkdocs build --strict -f mkdocs.public.yml
- name: "Build docs (insiders)"
if: ${{ env.MKDOCS_INSIDERS_SSH_KEY_EXISTS == 'true' }}
run: uvx --with-requirements docs/requirements-insiders.txt mkdocs build --strict -f mkdocs.insiders.yml
```
## /.github/workflows/daily_property_tests.yml
```yml path="/.github/workflows/daily_property_tests.yml"
name: Daily property test run
on:
workflow_dispatch:
schedule:
- cron: "0 12 * * *"
pull_request:
paths:
- ".github/workflows/daily_property_tests.yml"
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
env:
CARGO_INCREMENTAL: 0
CARGO_NET_RETRY: 10
CARGO_TERM_COLOR: always
RUSTUP_MAX_RETRIES: 10
FORCE_COLOR: 1
jobs:
property_tests:
name: Property tests
runs-on: ubuntu-latest
timeout-minutes: 20
# Don't run the cron job on forks:
if: ${{ github.repository == 'astral-sh/ty' || github.event_name != 'schedule' }}
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
repository: astral-sh/ruff
- name: "Install Rust toolchain"
run: rustup show
- name: "Install mold"
uses: rui314/setup-mold@725a8794d15fc7563f59595bd9556495c0564878 # v1
- uses: Swatinem/rust-cache@f13886b937689c021905a6b90929199931d60db1 # v2.8.1
- name: Build ty
# A release build takes longer (2 min vs 1 min), but the property tests run much faster in release
# mode (1.5 min vs 14 min), so the overall time is shorter with a release build.
run: cargo build --locked --release --package ty_python_semantic --tests
- name: Run property tests
shell: bash
run: |
export QUICKCHECK_TESTS=100000
for _ in {1..5}; do
cargo test --locked --release --package ty_python_semantic -- --ignored list::property_tests
cargo test --locked --release --package ty_python_semantic -- --ignored types::property_tests::stable
done
create-issue-on-failure:
name: Create an issue if the daily property test run surfaced any bugs
runs-on: ubuntu-latest
needs: property_tests
if: ${{ github.repository == 'astral-sh/ty' && always() && github.event_name == 'schedule' && needs.property_tests.result == 'failure' }}
permissions:
issues: write
steps:
- uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
await github.rest.issues.create({
owner: "astral-sh",
repo: "ty",
title: `Daily property test run failed on ${new Date().toDateString()}`,
body: "Run listed here: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
labels: ["bug", "type properties"],
})
```
## /.github/workflows/publish-docs.yml
```yml path="/.github/workflows/publish-docs.yml"
# Publish the ty documentation.
#
# Assumed to run as a subworkflow of .github/workflows/release.yml; specifically, as a post-announce
# job within `cargo-dist`.
name: mkdocs
on:
workflow_dispatch:
inputs:
ref:
description: "The commit SHA, tag, or branch to publish. Uses the default branch if not specified."
default: ""
type: string
workflow_call:
inputs:
plan:
required: true
type: string
permissions:
contents: read
jobs:
mkdocs:
runs-on: ubuntu-latest
env:
MKDOCS_INSIDERS_SSH_KEY_EXISTS: ${{ secrets.MKDOCS_INSIDERS_SSH_KEY != '' }}
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
ref: ${{ inputs.ref }}
persist-credentials: true
- uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: 3.14
- name: "Set docs version"
env:
version: ${{ (inputs.plan != '' && fromJson(inputs.plan).announcement_tag) || inputs.ref }}
run: |
# if version is missing, use 'latest'
if [ -z "$version" ]; then
echo "Using 'latest' as version"
version="latest"
fi
# Use version as display name for now
display_name="$version"
echo "version=$version" >> "$GITHUB_ENV"
echo "display_name=$display_name" >> "$GITHUB_ENV"
- name: "Set branch name"
run: |
timestamp="$(date +%s)"
# create branch_display_name from display_name by replacing all
# characters disallowed in git branch names with hyphens
branch_display_name="$(echo "${display_name}" | tr -c '[:alnum:]._' '-' | tr -s '-')"
echo "branch_name=update-docs-$branch_display_name-$timestamp" >> "$GITHUB_ENV"
echo "timestamp=$timestamp" >> "$GITHUB_ENV"
- name: "Add SSH key"
if: ${{ env.MKDOCS_INSIDERS_SSH_KEY_EXISTS == 'true' }}
uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1
with:
ssh-private-key: ${{ secrets.MKDOCS_INSIDERS_SSH_KEY }}
- name: "Install Insiders dependencies"
if: ${{ env.MKDOCS_INSIDERS_SSH_KEY_EXISTS == 'true' }}
run: pip install -r docs/requirements-insiders.txt
- name: "Install dependencies"
if: ${{ env.MKDOCS_INSIDERS_SSH_KEY_EXISTS != 'true' }}
run: pip install -r docs/requirements.txt
- name: "Build Insiders docs"
if: ${{ env.MKDOCS_INSIDERS_SSH_KEY_EXISTS == 'true' }}
run: mkdocs build --strict -f mkdocs.insiders.yml
- name: "Build docs"
if: ${{ env.MKDOCS_INSIDERS_SSH_KEY_EXISTS != 'true' }}
run: mkdocs build --strict -f mkdocs.public.yml
- name: "Clone docs repo"
run: git clone https://${{ secrets.ASTRAL_DOCS_PAT }}@github.com/astral-sh/docs.git astral-docs
- name: "Copy docs"
run: rm -rf astral-docs/site/ty && mkdir -p astral-docs/site && cp -r site/ty astral-docs/site/
- name: "Commit docs"
working-directory: astral-docs
run: |
git config user.name "astral-docs-bot"
git config user.email "176161322+astral-docs-bot@users.noreply.github.com"
git checkout -b "${branch_name}"
git add site/ty
git commit -m "Update ty documentation for $version"
- name: "Create Pull Request"
working-directory: astral-docs
env:
GITHUB_TOKEN: ${{ secrets.ASTRAL_DOCS_PAT }}
run: |
# set the PR title
pull_request_title="Update ty documentation for ${display_name}"
# Delete any existing pull requests that are open for this version
# by checking against pull_request_title because the new PR will
# supersede the old one.
gh pr list --state open --json title --jq '.[] | select(.title == "$pull_request_title") | .number' | \
xargs -I {} gh pr close {}
# push the branch to GitHub
git push origin "${branch_name}"
# create the PR
gh pr create \
--base=main \
--head="${branch_name}" \
--title="${pull_request_title}" \
--body="Automated documentation update for ${display_name}" \
--label="documentation"
- name: "Merge Pull Request"
if: ${{ inputs.plan != '' && !fromJson(inputs.plan).announcement_tag_is_implicit }}
working-directory: astral-docs
env:
GITHUB_TOKEN: ${{ secrets.ASTRAL_DOCS_PAT }}
run: |
# auto-merge the PR if the build was triggered by a release. Manual builds should be reviewed by a human.
# give the PR a few seconds to be created before trying to auto-merge it
sleep 10
gh pr merge --squash "${branch_name}"
```
## /.github/workflows/publish-pypi.yml
```yml path="/.github/workflows/publish-pypi.yml"
# Publish a release to PyPI.
#
# Assumed to run as a subworkflow of .github/workflows/release.yml; specifically, as a publish job
# within `cargo-dist`.
name: "Publish to PyPI"
on:
workflow_call:
inputs:
plan:
required: true
type: string
jobs:
pypi-publish:
name: Upload to PyPI
runs-on: ubuntu-latest
environment:
name: release
permissions:
# For PyPI's trusted publishing.
id-token: write
steps:
- name: "Install uv"
uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 # v7.1.2
- uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
with:
pattern: wheels-*
path: wheels
merge-multiple: true
- name: Publish to PyPi
run: uv publish -v wheels/*
```
## /.github/workflows/release.yml
```yml path="/.github/workflows/release.yml"
# This file was autogenerated by dist: https://axodotdev.github.io/cargo-dist
#
# Copyright 2022-2024, axodotdev
# SPDX-License-Identifier: MIT or Apache-2.0
#
# CI that:
#
# * checks for a Git Tag that looks like a release
# * builds artifacts with dist (archives, installers, hashes)
# * uploads those artifacts to temporary workflow zip
# * on success, uploads the artifacts to a GitHub Release
#
# Note that the GitHub Release will be created with a generated
# title/body based on your changelogs.
name: Release
permissions:
"contents": "write"
# This task will run whenever you workflow_dispatch with a tag that looks like a version
# like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc.
# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where
# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION
# must be a Cargo-style SemVer Version (must have at least major.minor.patch).
#
# If PACKAGE_NAME is specified, then the announcement will be for that
# package (erroring out if it doesn't have the given version or isn't dist-able).
#
# If PACKAGE_NAME isn't specified, then the announcement will be for all
# (dist-able) packages in the workspace with that version (this mode is
# intended for workspaces with only one dist-able package, or with all dist-able
# packages versioned/released in lockstep).
#
# If you push multiple tags at once, separate instances of this workflow will
# spin up, creating an independent announcement for each one. However, GitHub
# will hard limit this to 3 tags per commit, as it will assume more tags is a
# mistake.
#
# If there's a prerelease-style suffix to the version, then the release(s)
# will be marked as a prerelease.
on:
pull_request:
workflow_dispatch:
inputs:
tag:
description: Release Tag
required: true
default: dry-run
type: string
jobs:
# Run 'dist plan' (or host) to determine what tasks we need to do
plan:
runs-on: "depot-ubuntu-latest-4"
outputs:
val: ${{ steps.plan.outputs.manifest }}
tag: ${{ (inputs.tag != 'dry-run' && inputs.tag) || '' }}
tag-flag: ${{ inputs.tag && inputs.tag != 'dry-run' && format('--tag={0}', inputs.tag) || '' }}
publishing: ${{ inputs.tag && inputs.tag != 'dry-run' }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493
with:
persist-credentials: false
submodules: recursive
- name: Install dist
# we specify bash to get pipefail; it guards against the `curl` command
# failing. otherwise `sh` won't catch that `curl` returned non-0
shell: bash
run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.30.0/cargo-dist-installer.sh | sh"
- name: Cache dist
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4
with:
name: cargo-dist-cache
path: ~/.cargo/bin/dist
# sure would be cool if github gave us proper conditionals...
# so here's a doubly-nested ternary-via-truthiness to try to provide the best possible
# functionality based on whether this is a pull_request, and whether it's from a fork.
# (PRs run on the *source* but secrets are usually on the *target* -- that's *good*
# but also really annoying to build CI around when it needs secrets to work right.)
- id: plan
run: |
dist ${{ (inputs.tag && inputs.tag != 'dry-run' && format('host --steps=create --tag={0}', inputs.tag)) || 'plan' }} --output-format=json > plan-dist-manifest.json
echo "dist ran successfully"
cat plan-dist-manifest.json
echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT"
- name: "Upload dist-manifest.json"
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4
with:
name: artifacts-plan-dist-manifest
path: plan-dist-manifest.json
custom-build-binaries:
needs:
- plan
if: ${{ needs.plan.outputs.publishing == 'true' || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == 'upload' || inputs.tag == 'dry-run' }}
uses: ./.github/workflows/build-binaries.yml
with:
plan: ${{ needs.plan.outputs.val }}
secrets: inherit
custom-build-docker:
needs:
- plan
if: ${{ needs.plan.outputs.publishing == 'true' || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == 'upload' || inputs.tag == 'dry-run' }}
uses: ./.github/workflows/build-docker.yml
with:
plan: ${{ needs.plan.outputs.val }}
secrets: inherit
permissions:
"contents": "read"
"packages": "write"
# Build and package all the platform-agnostic(ish) things
build-global-artifacts:
needs:
- plan
- custom-build-binaries
- custom-build-docker
runs-on: "depot-ubuntu-latest-4"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json
steps:
- uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493
with:
persist-credentials: false
submodules: recursive
- name: Install cached dist
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53
with:
name: cargo-dist-cache
path: ~/.cargo/bin/
- run: chmod +x ~/.cargo/bin/dist
# Get all the local artifacts for the global tasks to use (for e.g. checksums)
- name: Fetch local artifacts
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53
with:
pattern: artifacts-*
path: target/distrib/
merge-multiple: true
- id: cargo-dist
shell: bash
run: |
dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json
echo "dist ran successfully"
# Parse out what we just built and upload it to scratch storage
echo "paths<<EOF" >> "$GITHUB_OUTPUT"
jq --raw-output ".upload_files[]" dist-manifest.json >> "$GITHUB_OUTPUT"
echo "EOF" >> "$GITHUB_OUTPUT"
cp dist-manifest.json "$BUILD_MANIFEST_NAME"
- name: "Upload artifacts"
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4
with:
name: artifacts-build-global
path: |
${{ steps.cargo-dist.outputs.paths }}
${{ env.BUILD_MANIFEST_NAME }}
# Determines if we should publish/announce
host:
needs:
- plan
- custom-build-binaries
- custom-build-docker
- build-global-artifacts
# Only run if we're "publishing", and only if local and global didn't fail (skipped is fine)
if: ${{ always() && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.custom-build-binaries.result == 'skipped' || needs.custom-build-binaries.result == 'success') && (needs.custom-build-docker.result == 'skipped' || needs.custom-build-docker.result == 'success') }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
runs-on: "depot-ubuntu-latest-4"
outputs:
val: ${{ steps.host.outputs.manifest }}
steps:
- uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493
with:
persist-credentials: false
submodules: recursive
- name: Install cached dist
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53
with:
name: cargo-dist-cache
path: ~/.cargo/bin/
- run: chmod +x ~/.cargo/bin/dist
# Fetch artifacts from scratch-storage
- name: Fetch artifacts
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53
with:
pattern: artifacts-*
path: target/distrib/
merge-multiple: true
# This is a harmless no-op for GitHub Releases, hosting for that happens in "announce"
- id: host
shell: bash
run: |
dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json
echo "artifacts uploaded and released successfully"
cat dist-manifest.json
echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT"
- name: "Upload dist-manifest.json"
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4
with:
# Overwrite the previous copy
name: artifacts-dist-manifest
path: dist-manifest.json
custom-publish-pypi:
needs:
- plan
- host
if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}
uses: ./.github/workflows/publish-pypi.yml
with:
plan: ${{ needs.plan.outputs.val }}
secrets: inherit
# publish jobs get escalated permissions
permissions:
"id-token": "write"
"packages": "write"
# Create a GitHub Release while uploading all files to it
announce:
needs:
- plan
- host
- custom-publish-pypi
# use "always() && ..." to allow us to wait for all publish jobs while
# still allowing individual publish jobs to skip themselves (for prereleases).
# "host" however must run to completion, no skipping allowed!
if: ${{ always() && needs.host.result == 'success' && (needs.custom-publish-pypi.result == 'skipped' || needs.custom-publish-pypi.result == 'success') }}
runs-on: "depot-ubuntu-latest-4"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493
with:
persist-credentials: false
submodules: recursive
# Create a GitHub Release while uploading all files to it
- name: "Download GitHub Artifacts"
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53
with:
pattern: artifacts-*
path: artifacts
merge-multiple: true
- name: Cleanup
run: |
# Remove the granular manifests
rm -f artifacts/*-dist-manifest.json
- name: Create GitHub Release
env:
PRERELEASE_FLAG: "${{ fromJson(needs.host.outputs.val).announcement_is_prerelease && '--prerelease' || '' }}"
ANNOUNCEMENT_TITLE: "${{ fromJson(needs.host.outputs.val).announcement_title }}"
ANNOUNCEMENT_BODY: "${{ fromJson(needs.host.outputs.val).announcement_github_body }}"
RELEASE_COMMIT: "${{ github.sha }}"
run: |
# Write and read notes from a file to avoid quoting breaking things
echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt
gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/*
custom-publish-docs:
needs:
- plan
- announce
uses: ./.github/workflows/publish-docs.yml
with:
plan: ${{ needs.plan.outputs.val }}
secrets: inherit
```
## /.gitignore
```gitignore path="/.gitignore"
# Python-generated files
__pycache__/
*.py[oc]
build/
dist/
wheels/
*.egg-info
# Virtual environments
.venv
```
## /.gitmodules
```gitmodules path="/.gitmodules"
[submodule "ruff"]
path = ruff
url = https://github.com/astral-sh/ruff
```
## /.markdownlint.yaml
```yaml path="/.markdownlint.yaml"
# default to true for all rules
default: true
# MD007/unordered-list-indent
MD007:
indent: 4
# MD033/no-inline-html
MD033: false
# MD041/first-line-h1
MD041: false
# MD013/line-length
MD013: false
# MD014/commands-show-output
MD014: false
# MD024/no-duplicate-heading
MD024:
# Allow when nested under different parents e.g. CHANGELOG.md
siblings_only: true
# MD046/code-block-style
#
# Ignore this because it conflicts with the code block style used in content
# tabs of mkdocs-material which is to add a blank line after the content title.
#
# Ref: https://github.com/astral-sh/ruff/pull/15011#issuecomment-2544790854
MD046: false
# Link text should be descriptive
# Disallows link text like *here* which is annoying.
MD059: false
```
## /.pre-commit-config.yaml
```yaml path="/.pre-commit-config.yaml"
fail_fast: false
exclude: |
(?x)^(
.github/workflows/release.yml
| ruff/.*
| docs/reference/(cli|configuration|rules|environment).md
)$
repos:
- repo: https://github.com/astral-sh/uv-pre-commit
rev: 0.9.7
hooks:
- id: uv-lock
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
hooks:
- id: check-merge-conflict
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.14.3
hooks:
- id: ruff-format
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
types_or: [python, pyi]
require_serial: true
- repo: https://github.com/abravalheri/validate-pyproject
rev: v0.24.1
hooks:
- id: validate-pyproject
- repo: https://github.com/executablebooks/mdformat
rev: 1.0.0
hooks:
- id: mdformat
language: python # means renovate will also update `additional_dependencies`
additional_dependencies:
- mdformat-mkdocs==4.4.2
- mdformat-footnote==0.1.2
- repo: https://github.com/igorshubovych/markdownlint-cli
rev: v0.45.0
hooks:
- id: markdownlint-fix
- repo: https://github.com/crate-ci/typos
rev: v1.39.0
hooks:
- id: typos
# Prettier
- repo: https://github.com/rbubley/mirrors-prettier
rev: v3.6.2
hooks:
- id: prettier
types: [yaml]
# zizmor detects security vulnerabilities in GitHub Actions workflows.
# Additional configuration for the tool is found in `.github/zizmor.yml`
- repo: https://github.com/zizmorcore/zizmor-pre-commit
rev: v1.16.2
hooks:
- id: zizmor
- repo: https://github.com/python-jsonschema/check-jsonschema
rev: 0.34.1
hooks:
- id: check-github-workflows
# `actionlint` hook, for verifying correct syntax in GitHub Actions workflows.
# Some additional configuration for `actionlint` can be found in `.github/actionlint.yaml`.
- repo: https://github.com/rhysd/actionlint
rev: v1.7.8
hooks:
- id: actionlint
stages:
# This hook is disabled by default, since it's quite slow.
# To run all hooks *including* this hook, use `uvx pre-commit run -a --hook-stage=manual`.
# To run *just* this hook, use `uvx pre-commit run -a actionlint --hook-stage=manual`.
- manual
args:
- "-ignore=SC2129" # ignorable stylistic lint from shellcheck
- "-ignore=SC2016" # another shellcheck lint: seems to have false positives?
additional_dependencies:
# actionlint has a shellcheck integration which extracts shell scripts in `run:` steps from GitHub Actions
# and checks these with shellcheck. This is arguably its most useful feature,
# but the integration only works if shellcheck is installed
- "github.com/wasilibs/go-shellcheck/cmd/shellcheck@v0.10.0"
```
## /.python-version
```python-version path="/.python-version"
3.13
```
## /CHANGELOG.md
# Changelog
## 0.0.1-alpha.25
Released on 2025-10-29.
### Bug fixes
- Fix bug where ty would think all types had an `__mro__` attribute ([#20995](https://github.com/astral-sh/ruff/pull/20995))
- Fix rare panic with highly cyclic `TypeVar` definitions ([#21059](https://github.com/astral-sh/ruff/pull/21059))
- Fix infinite recursion with generic type aliases ([#20969](https://github.com/astral-sh/ruff/pull/20969))
- Add missing newline before first diagnostic in CLI output ([#21058](https://github.com/astral-sh/ruff/pull/21058))
- Make the ty server's auto-import feature skip symbols in the current module ([#21100](https://github.com/astral-sh/ruff/pull/21100))
- Don't provide goto-definition for definitions which are not reexported in builtins ([#21127](https://github.com/astral-sh/ruff/pull/21127))
- Avoid duplicate diagnostics during multi-inference of standalone expressions ([#21056](https://github.com/astral-sh/ruff/pull/21056))
### Type inference and diagnostics
- Use constructor parameter types as context to inform solving type variables ([#21054](https://github.com/astral-sh/ruff/pull/21054))
- Consider `__len__` when determining the truthiness of an instance of a tuple class or a `@final` class ([#21049](https://github.com/astral-sh/ruff/pull/21049))
- Delegate truthiness inference of an enum `Literal` type to its enum-instance supertype ([#21060](https://github.com/astral-sh/ruff/pull/21060))
- Improve `invalid-argument-type` diagnostics where a union type was provided ([#21044](https://github.com/astral-sh/ruff/pull/21044))
### LSP server
- Suggest `type_check_only` items last in completions ([#20910](https://github.com/astral-sh/ruff/pull/20910))
- Render `import <...>` in completions when "label details" isn't supported ([#21109](https://github.com/astral-sh/ruff/pull/21109))
- Update workspace diagnostic progress every 50ms ([#21019](https://github.com/astral-sh/ruff/pull/21019))
### CLI
- Add `--no-progress` option to suppress the rendering of a progress bar ([#21063](https://github.com/astral-sh/ruff/pull/21063))
### Contributors
- [@ibraheemdev](https://github.com/ibraheemdev)
- [@MatthewMckee4](https://github.com/MatthewMckee4)
- [@BurntSushi](https://github.com/BurntSushi)
- [@mtshiba](https://github.com/mtshiba)
- [@AlexWaygood](https://github.com/AlexWaygood)
- [@MichaReiser](https://github.com/MichaReiser)
- [@decorator-factory](https://github.com/decorator-factory)
## 0.0.1-alpha.24
Released on 2025-10-23.
### Breaking changes
- Rename `unknown-rule` lint to `ignore-comment-unknown-rule` ([#20948](https://github.com/astral-sh/ruff/pull/20948))
### Type inference and diagnostics
- Infer a type of `Self` for unannotated `self` parameters in methods ([#20922](https://github.com/astral-sh/ruff/pull/20922))
- Prefer the declared type over the inferred type for invariant collection literals ([#20927](https://github.com/astral-sh/ruff/pull/20927))
- Use declared variable types as bidirectional type context for solving type variables ([#20796](https://github.com/astral-sh/ruff/pull/20796))
- Support `dataclass_transform` for base class models ([#20783](https://github.com/astral-sh/ruff/pull/20783))
- Support dataclass-transform `field_specifiers` ([#20888](https://github.com/astral-sh/ruff/pull/20888))
- `dataclass_transform` support for fields with an `alias` ([#20961](https://github.com/astral-sh/ruff/pull/20961))
- Add support for legacy namespace packages ([#20897](https://github.com/astral-sh/ruff/pull/20897))
- Add suggestion to "unknown rule" diagnostics ([#20948](https://github.com/astral-sh/ruff/pull/20948))
- Improve error messages for "unresolved attribute" diagnostics ([#20963](https://github.com/astral-sh/ruff/pull/20963))
- Avoid unnecessarily widening generic specializations ([#20875](https://github.com/astral-sh/ruff/pull/20875))
- Truncate `Literal` type display in some situations ([#20928](https://github.com/astral-sh/ruff/pull/20928))
### Bug fixes
- Fix panic involving cyclic `TypeVar` default ([#20967](https://github.com/astral-sh/ruff/pull/20967))
- Fix panic involving ever-growing default types ([#20991](https://github.com/astral-sh/ruff/pull/20991))
- Fix panic involving infinitely expanding implicit attribute types ([#20988](https://github.com/astral-sh/ruff/pull/20988))
- Fix autocomplete suggestions when the cursor is at the end of a file ([#20993](https://github.com/astral-sh/ruff/pull/20993))
- Fix inconsistent highlighting of self ([#20986](https://github.com/astral-sh/ruff/pull/20986))
- Fix out-of-order semantic token for function with regular argument after kwargs ([#21013](https://github.com/astral-sh/ruff/pull/21013))
- Fix panic on recursive class definitions in a stub that use constrained type variables ([#20955](https://github.com/astral-sh/ruff/pull/20955))
- Fix panic when attempting to validate the members of a protocol that inherits from a protocol in another module ([#20956](https://github.com/astral-sh/ruff/pull/20956))
- Fix rare hang relating to multithreading ([#21038](https://github.com/astral-sh/ruff/pull/21038))
- Fix non-deterministic overload function inference ([#20966](https://github.com/astral-sh/ruff/pull/20966))
- Fix auto-import edits made by autocompletions for files with an existing `from __future__` import ([#20987](https://github.com/astral-sh/ruff/pull/20987))
### LSP server
- Support goto-definition for binary and unary operators ([#21001](https://github.com/astral-sh/ruff/pull/21001))
- Support goto-definition on vendored typeshed stubs ([#21020](https://github.com/astral-sh/ruff/pull/21020))
- Provide completions on `TypeVar`s ([#20943](https://github.com/astral-sh/ruff/pull/20943))
- Display variance when hovering over type variables ([#20900](https://github.com/astral-sh/ruff/pull/20900))
- Avoid sending an unnecessary "clear diagnostics" message for clients supporting [pull diagnostics](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_pullDiagnostics). ([#20989](https://github.com/astral-sh/ruff/pull/20989))
### Other changes
- Report `continue` and `break` statements outside loops as syntax errors ([#20944](https://github.com/astral-sh/ruff/pull/20944))
### Contributors
- [@TaKO8Ki](https://github.com/TaKO8Ki)
- [@sharkdp](https://github.com/sharkdp)
- [@InvalidPathException](https://github.com/InvalidPathException)
- [@AlexWaygood](https://github.com/AlexWaygood)
- [@mtshiba](https://github.com/mtshiba)
- [@ibraheemdev](https://github.com/ibraheemdev)
- [@Gankra](https://github.com/Gankra)
- [@MichaReiser](https://github.com/MichaReiser)
## 0.0.1-alpha.23
Released on 2025-10-16.
### Bug fixes
- Fix handling of dataclass `field()`s without default values ([#20914](https://github.com/astral-sh/ruff/pull/20914))
- Fix false-positive diagnostics on `super()` calls ([#20814](https://github.com/astral-sh/ruff/pull/20814), [#20843](https://github.com/astral-sh/ruff/pull/20843))
- Fix `match` pattern value narrowing to use equality semantics ([#20882](https://github.com/astral-sh/ruff/pull/20882))
- Fix "missing root" panic when handling completion requests ([#20917](https://github.com/astral-sh/ruff/pull/20917))
- Fix overwriting of declared base class attributes through undeclared subclass members ([#20764](https://github.com/astral-sh/ruff/pull/20764))
- Fix runaway execution time for mutually referential instance attributes ([#20645](https://github.com/astral-sh/ruff/pull/20645))
### CLI
- For `unresolved-import` diagnostics, limit the shown import paths to at most five, unless in verbose mode ([#20912](https://github.com/astral-sh/ruff/pull/20912))
- Write files that are slow to type check to log output ([#20836](https://github.com/astral-sh/ruff/pull/20836))
- Remove "pre-release software" warning ([#20817](https://github.com/astral-sh/ruff/pull/20817))
### LSP server
- Improve ranking of autocomplete suggestions ([#20807](https://github.com/astral-sh/ruff/pull/20807))
### Type inference and diagnostics
- Use return type annotations as context for bidirectional type inference ([#20528](https://github.com/astral-sh/ruff/pull/20528))
- Use bidirectional type context for `TypedDict` construction ([#20806](https://github.com/astral-sh/ruff/pull/20806))
- Add support for unpacking of heterogeneous tuples in unions ([#20377](https://github.com/astral-sh/ruff/pull/20377))
- Add a new diagnostic for generic classes that reference typevars from an enclosing scope ([#20822](https://github.com/astral-sh/ruff/pull/20822))
- Add hint when accessing standard library module attributes that are not available on the configured Python version ([#20909](https://github.com/astral-sh/ruff/pull/20909))
- Treat functions, methods, and dynamic types as function-like `Callable`s ([#20842](https://github.com/astral-sh/ruff/pull/20842))
- Treat `Callable`s as bound-method descriptors in special cases ([#20802](https://github.com/astral-sh/ruff/pull/20802))
- Treat `Callable` dunder members as bound method descriptors ([#20860](https://github.com/astral-sh/ruff/pull/20860))
- Sync vendored typeshed stubs ([#20876](https://github.com/astral-sh/ruff/pull/20876)). [Typeshed diff](https://github.com/python/typeshed/compare/91055c730ffcda6311654cf32d663858ece69bad...d6f4a0f7102b1400a21742cf9b7ea93614e2b6ec)
### Performance improvements
- Improve performance by caching union simplification type relations ([#20477](https://github.com/astral-sh/ruff/pull/20477))
### Contributors
- [@mtshiba](https://github.com/mtshiba)
- [@AlexWaygood](https://github.com/AlexWaygood)
- [@ericmarkmartin](https://github.com/ericmarkmartin)
- [@carljm](https://github.com/carljm)
- [@ntBre](https://github.com/ntBre)
- [@sharkdp](https://github.com/sharkdp)
- [@BurntSushi](https://github.com/BurntSushi)
- [@Gankra](https://github.com/Gankra)
- [@MichaReiser](https://github.com/MichaReiser)
- [@dcreager](https://github.com/dcreager)
## 0.0.1-alpha.22
Released on 2025-10-10.
### Bug fixes
- Enforce that `typing_extensions` must come from a stdlib search path. This fixes a panic that could occur with a confusing backtrace if the `extra-paths` setting was incorrectly used to point to a virtual environment ([#20715](https://github.com/astral-sh/ruff/pull/20715))
- Fix server panic when opening a project located at `/` in the file system ([#20684](https://github.com/astral-sh/ruff/pull/20684))
- Fix panics when using `--output-format=gitlab` in CI environments ([#20550](https://github.com/astral-sh/ruff/pull/20550))
- Fix stack overflows that could occur when attempting to determine if a recursive `NamedTuple` type was disjoint from another type ([#20538](https://github.com/astral-sh/ruff/pull/20538))
- Fix panics in type inference when legacy TypeVars had bounds, constraints, or defaults that cyclically referred back to the TypeVar definition (directly or indirectly) ([#20598](https://github.com/astral-sh/ruff/pull/20598))
- Fix situations where a panic during resolution of type-checker query cycles would manifest in a hang ([#20577](https://github.com/astral-sh/ruff/pull/20577))
- When analyzing a .py file, do not error if there's also a .pyi for that module ([#20461](https://github.com/astral-sh/ruff/pull/20461))
- Recognise that the runtime object `typing.Protocol` is an instance of `_ProtocolMeta` ([#20488](https://github.com/astral-sh/ruff/pull/20488))
- Fix logic that attempted to determine whether a user had explicitly activated a Conda environment, which has implications for the search paths ty uses for module resolution ([#20675](https://github.com/astral-sh/ruff/pull/20675))
- Fix false negatives when iterables with the wrong type are unpacked into a function with a `*args` variadic parameter ([#20511](https://github.com/astral-sh/ruff/pull/20511))
### Support for Python 3.14
- Use 3.14 as the default version ([#20725](https://github.com/astral-sh/ruff/pull/20725), [#20759](https://github.com/astral-sh/ruff/pull/20759), [#20760](https://github.com/astral-sh/ruff/pull/20760))
- Annotations are deferred by default for 3.14+ ([#20799](https://github.com/astral-sh/ruff/pull/20799))
- Fix false positives when accessing `__annotate__` (Py3.14+) or `__warningregistry__` as a module global ([#20154](https://github.com/astral-sh/ruff/pull/20154))
### Improvements to `TypeVar` solving and inference of generic types
- Improve solving of a type variable `T` if it appears in a union with non-`TypeVar`s (`T | None`, `T | str | None`, etc.) ([#20749](https://github.com/astral-sh/ruff/pull/20749))
- More precise type inference for dictionary literals ([#20523](https://github.com/astral-sh/ruff/pull/20523))
- When solving type variables, use type context to inform whether `Literal` types should be promoted to instance types ([#20776](https://github.com/astral-sh/ruff/pull/20776))
- Use annotated parameters as type context when solving type variables ([#20635](https://github.com/astral-sh/ruff/pull/20635))
- Correctly infer the return type of method calls when the method is annotated as returning `Self` ([#20517](https://github.com/astral-sh/ruff/pull/20517), [#20754](https://github.com/astral-sh/ruff/pull/20754))
- Use type context for inference of generic function calls ([#20476](https://github.com/astral-sh/ruff/pull/20476))
- Use `C[T]` instead of `C[Unknown]` for the upper bound of `Self` ([#20479](https://github.com/astral-sh/ruff/pull/20479))
### Improvements to assignability, subtyping, and union simplification
- Fix overly strict assignability implementation for intersections with negated gradual elements ([#20773](https://github.com/astral-sh/ruff/pull/20773))
- Ensure that `C[Any]` is understood as a subtype of `C[object]` if `C` is a covariant generic class ([#20592](https://github.com/astral-sh/ruff/pull/20592))
- Ensure that `~T` is never considered to be assignable to `T` where `T` is a type variable ([#20606](https://github.com/astral-sh/ruff/pull/20606))
- Improve assignability/subtyping between two protocol types ([#20368](https://github.com/astral-sh/ruff/pull/20368))
- Simplify `Any | (Any & T)` to `Any` ([#20593](https://github.com/astral-sh/ruff/pull/20593))
- Optimise and generalise union/intersection simplification ([#20602](https://github.com/astral-sh/ruff/pull/20602))
- Make protocol satisfiability checks more principled when a protocol has a method member that is generic over type variables scoped to the function ([#20568](https://github.com/astral-sh/ruff/pull/20568))
- Fix subtyping of invariant generics specialized with `Any`, ensuring that (for example) `list[Any]` is not considered a subtype of `list[Any]` ([#20650](https://github.com/astral-sh/ruff/pull/20650))
### Server
- Add LSP debug information command ([#20379](https://github.com/astral-sh/ruff/pull/20379))
- Add support for inlay hints on attribute assignment ([#20485](https://github.com/astral-sh/ruff/pull/20485))
### Improvements to diagnostics
- Improve diagnostics when a positional-only parameter is passed using a keyword argument ([#20495](https://github.com/astral-sh/ruff/pull/20495))
- Improve disambiguations of class names in diagnostics ([#20603](https://github.com/astral-sh/ruff/pull/20603), [#20756](https://github.com/astral-sh/ruff/pull/20756))
- Improve diagnostics for bad `@overload` definitions ([#20745](https://github.com/astral-sh/ruff/pull/20745))
- Truncate type display for long unions in some situations ([#20730](https://github.com/astral-sh/ruff/pull/20730))
- Rename "possibly unbound" diagnostics to "possibly missing" ([#20492](https://github.com/astral-sh/ruff/pull/20492))
### Improvements to enum support
- Allow multiple aliases to point to the same member ([#20669](https://github.com/astral-sh/ruff/pull/20669))
- implement `auto()` for `StrEnum` ([#20524](https://github.com/astral-sh/ruff/pull/20524))
### Improvements to ty's `@overload` implementation
- Support single-starred argument for overload call ([#20223](https://github.com/astral-sh/ruff/pull/20223))
- Filter overloads using variadic parameters ([#20547](https://github.com/astral-sh/ruff/pull/20547))
### Other typing semantics and features
- Do not union the inferred type of a module-global symbol with `Unknown` for the symbol's type when accessed from external scopes ([#20664](https://github.com/astral-sh/ruff/pull/20664))
- Ensure that class objects are understood as callable even if they do not override `object.__new__` or `object.__init__` ([#20521](https://github.com/astral-sh/ruff/pull/20521))
- Add support for `**kwargs` ([#20430](https://github.com/astral-sh/ruff/pull/20430))
- Ensure first-party module-resolution search paths always appear in a sensible order ([#20629](https://github.com/astral-sh/ruff/pull/20629))
- Respect `dataclass_transform` parameters for metaclass-based models ([#20780](https://github.com/astral-sh/ruff/pull/20780))
- Sync vendored typeshed stubs ([#20658](https://github.com/astral-sh/ruff/pull/20658)). [Typeshed diff](https://github.com/python/typeshed/compare/47dbbd6c914a5190d54bc5bd498d1e6633d97db2...91055c730ffcda6311654cf32d663858ece69bad)
- Bring ty's `TypeIs` narrowing behaviour closer to ty's narrowing behaviour for `isinstance()` checks. ([#20591](https://github.com/astral-sh/ruff/pull/20591))
- `dataclass_transform`: Support `frozen_default` and `kw_only_default` ([#20761](https://github.com/astral-sh/ruff/pull/20761))
- Allow any string `Literal` type expression as a key when constructing a `TypedDict` ([#20792](https://github.com/astral-sh/ruff/pull/20792))
- Add `--venv` as an alias to `--python` on the command line ([#20718](https://github.com/astral-sh/ruff/pull/20718))
- Add search paths listed in `PYTHONPATH` to search paths used for ty's module resolution ([#20441](https://github.com/astral-sh/ruff/pull/20441), [#20490](https://github.com/astral-sh/ruff/pull/20490))
### Contributors
- [@thejchap](https://github.com/thejchap)
- [@mtshiba](https://github.com/mtshiba)
- [@Danielkonge](https://github.com/Danielkonge)
- [@dcreager](https://github.com/dcreager)
- [@MatthewMckee4](https://github.com/MatthewMckee4)
- [@Gankra](https://github.com/Gankra)
- [@BurntSushi](https://github.com/BurntSushi)
- [@carljm](https://github.com/carljm)
- [@dhruvmanila](https://github.com/dhruvmanila)
- [@sharkdp](https://github.com/sharkdp)
- [@mmlb](https://github.com/mmlb)
- [@fgiacome](https://github.com/fgiacome)
- [@Guillaume-Fgt](https://github.com/Guillaume-Fgt)
- [@AlexWaygood](https://github.com/AlexWaygood)
- [@Renkai](https://github.com/Renkai)
- [@InvalidPathException](https://github.com/InvalidPathException)
- [@ibraheemdev](https://github.com/ibraheemdev)
- [@fatelei](https://github.com/fatelei)
- [@github-actions](https://github.com/github-actions)
- [@MichaReiser](https://github.com/MichaReiser)
- [@ntBre](https://github.com/ntBre)
- [@danparizher](https://github.com/danparizher)
## 0.0.1-alpha.21
### Bug fixes
- Fix inference of constructor calls to generic classes that have explicitly annotated `self` parameters in their `__init__` methods ([#20325](https://github.com/astral-sh/ruff/pull/20325))
- Fix a stack overflow when computing completions for recursive types ([#20354](https://github.com/astral-sh/ruff/pull/20354))
- Fix panic in `BoundMethodType::into_callable_type()` ([#20369](https://github.com/astral-sh/ruff/pull/20369))
- Fix stack overflows in binary comparison inference ([#20446](https://github.com/astral-sh/ruff/pull/20446))
- Fix many "too many cycle iterations" panics concerning recursive type aliases and/or recursive generics ([#20359](https://github.com/astral-sh/ruff/pull/20359))
- Fix stack overflow involving subtype checks for recursive type aliases ([#20259](https://github.com/astral-sh/ruff/pull/20259))
- Fix panic when inferring the type of an infinitely-nested-tuple implicit instance attribute ([#20333](https://github.com/astral-sh/ruff/pull/20333))
### Server
- Add autocomplete suggestions for unimported symbols ([#20207](https://github.com/astral-sh/ruff/pull/20207), [#20439](https://github.com/astral-sh/ruff/pull/20439))
- Include generated `NamedTuple` methods such as `_make`, `_asdict` and `_replace` in autocomplete suggestions ([#20356](https://github.com/astral-sh/ruff/pull/20356))
### Configuration
- Automatically add `python/` to `environment.root` if a `python/` folder exists in the root of a repository ([#20263](https://github.com/astral-sh/ruff/pull/20263))
### CLI
- Add GitHub output format ([#20358](https://github.com/astral-sh/ruff/pull/20358))
- Add GitLab output format ([#20155](https://github.com/astral-sh/ruff/pull/20155))
### Typing semantics and features
- Add support for generic [PEP-695 type aliases](https://peps.python.org/pep-0695/#generic-type-alias) ([#20219](https://github.com/astral-sh/ruff/pull/20219))
- Allow annotation expressions to be `ast::Attribute` nodes ([#20413](https://github.com/astral-sh/ruff/pull/20413))
- Allow protocols to participate in nominal subtyping as well as structural subtyping ([#20314](https://github.com/astral-sh/ruff/pull/20314))
- Attribute access on top/bottom materializations ([#20221](https://github.com/astral-sh/ruff/pull/20221))
- Bind `Self` type variables to the method, not the class ([#20366](https://github.com/astral-sh/ruff/pull/20366))
- Ensure various special-cased bound methods are understood as assignable to `Callable` ([#20330](https://github.com/astral-sh/ruff/pull/20330))
- Ensure various special-cased builtin functions are understood as assignable to `Callable` ([#20331](https://github.com/astral-sh/ruff/pull/20331))
- Fall back to `object` for attribute access on synthesized protocols ([#20286](https://github.com/astral-sh/ruff/pull/20286))
- Fix signature of `NamedTupleLike._make` ([#20302](https://github.com/astral-sh/ruff/pull/20302))
- Fix subtyping/assignability of function- and class-literal types to callback protocols ([#20363](https://github.com/astral-sh/ruff/pull/20363))
- Implement the legacy PEP-484 convention for indicating positional-only parameters ([#20248](https://github.com/astral-sh/ruff/pull/20248))
- Infer more precise types for collection literals ([#20360](https://github.com/astral-sh/ruff/pull/20360))
- Make `TypeIs` invariant in its type argument ([#20428](https://github.com/astral-sh/ruff/pull/20428))
- Narrow specialized generics using `isinstance()` ([#20256](https://github.com/astral-sh/ruff/pull/20256))
- Proper assignability/subtyping checks for protocols with method members ([#20165](https://github.com/astral-sh/ruff/pull/20165))
- Reduce false positives for `ParamSpec`s and `TypeVarTuple`s ([#20239](https://github.com/astral-sh/ruff/pull/20239))
- Overload evaluation: retry parameter matching for argument type expansion ([#20153](https://github.com/astral-sh/ruff/pull/20153))
- Simplify unions of enum literals and subtypes thereof ([#20324](https://github.com/astral-sh/ruff/pull/20324))
- Support "legacy" `typing.Self` in combination with [PEP-695](https://peps.python.org/pep-0695) generic contexts ([#20304](https://github.com/astral-sh/ruff/pull/20304))
- Treat `Hashable`, and similar protocols, equivalently to `object` for subtyping/assignability ([#20284](https://github.com/astral-sh/ruff/pull/20284))
- Treat `__new__` as a static method ([#20212](https://github.com/astral-sh/ruff/pull/20212))
- `TypedDict`: Add support for `typing.ReadOnly` ([#20241](https://github.com/astral-sh/ruff/pull/20241))
- Detect syntax errors stemming from `yield from` expressions inside async functions ([#20051](https://github.com/astral-sh/ruff/pull/20051))
- `"foo".startswith` is not an instance of `types.MethodWrapperType` ([#20317](https://github.com/astral-sh/ruff/pull/20317))
- Eliminate definitely-impossible types from union in equality narrowing ([#20164](https://github.com/astral-sh/ruff/pull/20164))
- Infer more precise types for the `name` and `value` properties on enum members ([#20311](https://github.com/astral-sh/ruff/pull/20311))
- Initial support for `slots=True` in dataclasses ([#20278](https://github.com/astral-sh/ruff/pull/20278))
- Improve type narrowing in situations involving nested functions ([#19932](https://github.com/astral-sh/ruff/pull/19932))
- Support type aliases in binary comparison inference ([#20445](https://github.com/astral-sh/ruff/pull/20445))
- Sync vendored typeshed stubs ([#20394](https://github.com/astral-sh/ruff/pull/20394)). [Typeshed diff](https://github.com/python/typeshed/compare/2480d7e7c74493a024eaf254c5d2c6f452c80ee2...47dbbd6c914a5190d54bc5bd498d1e6633d97db2)
### Diagnostics
- Improve specialization-error diagnostics ([#20326](https://github.com/astral-sh/ruff/pull/20326))
### Contributors
- [@thejchap](https://github.com/thejchap)
- [@AlexWaygood](https://github.com/AlexWaygood)
- [@mtshiba](https://github.com/mtshiba)
- [@JelleZijlstra](https://github.com/JelleZijlstra)
- [@ibraheemdev](https://github.com/ibraheemdev)
- [@TaKO8Ki](https://github.com/TaKO8Ki)
- [@Glyphack](https://github.com/Glyphack)
- [@ericmarkmartin](https://github.com/ericmarkmartin)
- [@Renkai](https://github.com/Renkai)
- [@sharkdp](https://github.com/sharkdp)
- [@11happy](https://github.com/11happy)
- [@BurntSushi](https://github.com/BurntSushi)
- [@carljm](https://github.com/carljm)
- [@dhruvmanila](https://github.com/dhruvmanila)
- [@github-actions](https://github.com/github-actions)
- [@ntBre](https://github.com/ntBre)
## 0.0.1-alpha.20
### Bug fixes
- Server: Cancel background tasks when shutdown is requested ([#20039](https://github.com/astral-sh/ruff/pull/20039))
- Server: Close signature help after `)` ([#20017](https://github.com/astral-sh/ruff/pull/20017))
- Server: Fix incorrect docstring in call signature completion ([#20021](https://github.com/astral-sh/ruff/pull/20021))
- Fix 'too many cycle iterations' for unions of literals ([#20137](https://github.com/astral-sh/ruff/pull/20137))
- Fix namespace packages that behave like partial stubs ([#19994](https://github.com/astral-sh/ruff/pull/19994))
- Fix server hang (unchanged diagnostics) when changing file on Windows ([#19991](https://github.com/astral-sh/ruff/pull/19991))
- Apply `KW_ONLY` sentinel only to local fields ([#19986](https://github.com/astral-sh/ruff/pull/19986))
- Ignore field specifiers when not specified in `@dataclass_transform` ([#20002](https://github.com/astral-sh/ruff/pull/20002))
### Server
- Add completion support for `import` and `from ... import` statements ([#19883](https://github.com/astral-sh/ruff/pull/19883))
- Add type as detail to completion items ([#20047](https://github.com/astral-sh/ruff/pull/20047))
- Ask the LSP client to watch all project search paths ([#19975](https://github.com/astral-sh/ruff/pull/19975))
- Fix incorrect inlay hint type ([#20044](https://github.com/astral-sh/ruff/pull/20044))
- Update goto definition, goto declaration and hover to consider constructor method (`__init__`) ([#20014](https://github.com/astral-sh/ruff/pull/20014))
- Add docstrings to completions based on type ([#20008](https://github.com/astral-sh/ruff/pull/20008))
- Fix goto targets for keyword arguments in nested function calls ([#20013](https://github.com/astral-sh/ruff/pull/20013))
- Introduce multiline pretty printer to render function signatures across multiple lines ([#19979](https://github.com/astral-sh/ruff/pull/19979))
### Configuration
- Distinguish base conda from child conda ([#19990](https://github.com/astral-sh/ruff/pull/19990))
### Typing semantics and features
- Add support for PEP 750: t-strings ([#20085](https://github.com/astral-sh/ruff/pull/20085))
- Add support for PEP 800: Disjoint bases ([#20084](https://github.com/astral-sh/ruff/pull/20084))
- Add precise inference for unpacking a TypeVar if the TypeVar has an upper bound with a precise tuple spec ([#19985](https://github.com/astral-sh/ruff/pull/19985))
- Add precise iteration and unpacking inference for string literals and bytes literals ([#20023](https://github.com/astral-sh/ruff/pull/20023))
- Completely ignore typeshed's stub for `Any` ([#20079](https://github.com/astral-sh/ruff/pull/20079))
- Enforce that an attribute on a class `X` must be callable in order to satisfy a member on a protocol `P` ([#20142](https://github.com/astral-sh/ruff/pull/20142))
- Evaluate static truthiness of non-definitely-bound symbols to "ambiguous" ([#19579](https://github.com/astral-sh/ruff/pull/19579))
- Fix the inferred interface of specialized generic protocols ([#19866](https://github.com/astral-sh/ruff/pull/19866))
- Infer slightly more precise types for comprehensions ([#20111](https://github.com/astral-sh/ruff/pull/20111))
- Disable boundness analysis for implicit instance attributes ([#20128](https://github.com/astral-sh/ruff/pull/20128))
- Add `Top[]` and `Bottom[]` special forms ([#20054](https://github.com/astral-sh/ruff/pull/20054))
- Preserve qualifiers when accessing attributes on unions/intersections ([#20114](https://github.com/astral-sh/ruff/pull/20114))
- Strict validation of protocol members ([#17750](https://github.com/astral-sh/ruff/pull/17750))
- Support `__init_subclass__` ([#20190](https://github.com/astral-sh/ruff/pull/20190))
- Unpack variadic argument type in specialization ([#20130](https://github.com/astral-sh/ruff/pull/20130))
- Use `invalid-assignment` error code for invalid assignments to `ClassVar`s ([#20156](https://github.com/astral-sh/ruff/pull/20156))
- Use specialized parameter type for overload filter ([#19964](https://github.com/astral-sh/ruff/pull/19964))
- `__class_getitem__` is a classmethod ([#20192](https://github.com/astral-sh/ruff/pull/20192))
- Add cycle detection for find_legacy_typevars ([#20124](https://github.com/astral-sh/ruff/pull/20124))
- Add support for cyclic legacy generic protocols ([#20125](https://github.com/astral-sh/ruff/pull/20125))
- Don't eagerly unpack aliases in user-authored unions ([#20055](https://github.com/astral-sh/ruff/pull/20055))
- Don't mark entire type-alias scopes as Deferred ([#20086](https://github.com/astral-sh/ruff/pull/20086))
- Ensure union normalization really normalizes ([#20147](https://github.com/astral-sh/ruff/pull/20147))
- Improve cycle-detection coverage for apply_type_mapping ([#20159](https://github.com/astral-sh/ruff/pull/20159))
- Linear variance inference for PEP-695 type parameters ([#18713](https://github.com/astral-sh/ruff/pull/18713))
- Minor `TypedDict` fixes ([#20146](https://github.com/astral-sh/ruff/pull/20146))
- Typecheck dict methods for `TypedDict` ([#19874](https://github.com/astral-sh/ruff/pull/19874))
- Validate constructor call of `TypedDict` ([#19810](https://github.com/astral-sh/ruff/pull/19810))
- Sync vendored typeshed stubs ([#20031](https://github.com/astral-sh/ruff/pull/20031), [#20083](https://github.com/astral-sh/ruff/pull/20083), [#20188](https://github.com/astral-sh/ruff/pull/20188)) [Typeshed diff](https://github.com/python/typeshed/compare/893b9a760deb3be64d13c748318e95a752230961...2480d7e7c74493a024eaf254c5d2c6f452c80ee2)
### Diagnostics
- Add search paths info to unresolved import diagnostics ([#20040](https://github.com/astral-sh/ruff/pull/20040))
- Better error message for attempting to assign to a read-only property ([#20150](https://github.com/astral-sh/ruff/pull/20150))
- Improve diagnostics for bad calls to functions ([#20022](https://github.com/astral-sh/ruff/pull/20022))
- Improve disambiguation of types via fully qualified names ([#20141](https://github.com/astral-sh/ruff/pull/20141))
- Print diagnostics with fully qualified name to disambiguate some cases ([#19850](https://github.com/astral-sh/ruff/pull/19850))
### Performance
- Avoid unnecessary argument type expansion ([#19999](https://github.com/astral-sh/ruff/pull/19999))
- Limit argument expansion size for overload call evaluation ([#20041](https://github.com/astral-sh/ruff/pull/20041))
- Optimize TDD atom ordering ([#20098](https://github.com/astral-sh/ruff/pull/20098))
### Contributors
- [@carljm](https://github.com/carljm)
- [@sharkdp](https://github.com/sharkdp)
- [@dylwil3](https://github.com/dylwil3)
- [@dcreager](https://github.com/dcreager)
- [@MichaReiser](https://github.com/MichaReiser)
- [@ericmarkmartin](https://github.com/ericmarkmartin)
- [@Renkai](https://github.com/Renkai)
- [@JelleZijlstra](https://github.com/JelleZijlstra)
- [@BurntSushi](https://github.com/BurntSushi)
- [@AlexWaygood](https://github.com/AlexWaygood)
- [@github-actions](https://github.com/github-actions)
- [@PrettyWood](https://github.com/PrettyWood)
- [@dhruvmanila](https://github.com/dhruvmanila)
- [@Glyphack](https://github.com/Glyphack)
- [@Gankra](https://github.com/Gankra)
- [@MatthewMckee4](https://github.com/MatthewMckee4)
- [@leandrobbraga](https://github.com/leandrobbraga)
## 0.0.1-alpha.19
### Bug fixes
- Fix false-positive diagnostics if a function parameter is annotated with `type[P]` where `P` is a protocol class ([#19947](https://github.com/astral-sh/ruff/pull/19947))
- Fix ANSI colors in terminal output on old Windows terminals ([#19984](https://github.com/astral-sh/ruff/pull/19984))
- Fix protocol interface inference for protocols in stub files with `ClassVar` members and "subprotocols" that extend other protocols ([#19950](https://github.com/astral-sh/ruff/pull/19950))
- Fix inference of equality comparisons between enum members ([#19666](https://github.com/astral-sh/ruff/pull/19666))
- Remove incorrect type narrowing for `if type(x) is C[int]` ([#19926](https://github.com/astral-sh/ruff/pull/19926))
- Improve detection of `TypeError`s resulting from protocol classes illegally inheriting from non-protocol classes ([#19941](https://github.com/astral-sh/ruff/pull/19941)). We previously detected this error, but only when the protocol class illegally inherited from a non-generic class or an unspecialized generic class. We now also detect it when the protocol class inherits from a specialized generic class.
- Fix incorrectly precise type inference in some situations involving nested scopes ([#19908](https://github.com/astral-sh/ruff/pull/19908))
- Fix unpacking a type alias with a precise tuple spec ([#19981](https://github.com/astral-sh/ruff/pull/19981))
### `NamedTuple` semantics improvements
- Synthesize read-only properties for all declared members on `NamedTuple` classes ([#19899](https://github.com/astral-sh/ruff/pull/19899))
- Allow any instance of a `NamedTuple` class to be passed to a function parameter annotated with `typing.NamedTuple` ([#19915](https://github.com/astral-sh/ruff/pull/19915))
- Detect `NamedTuple` classes where fields without default values illegally follow fields with default values ([#19945](https://github.com/astral-sh/ruff/pull/19945)). This causes `TypeError` to be raised at runtime.
- Detect illegal multiple inheritance with `NamedTuple` ([#19943](https://github.com/astral-sh/ruff/pull/19943)). This causes `TypeError` to be raised at runtime.
### Other typing and semantics improvements
- Add support for stubs packages with `partial` in their `py.typed` files ([#19931](https://github.com/astral-sh/ruff/pull/19931))
- Look for `site-packages` directories in `<sys.prefix>/lib64/` as well as `<sys.prefix>/lib/` on non-Windows systems ([#19978](https://github.com/astral-sh/ruff/pull/19978)). This change fixes a number of `unresolved-import` false-positive diagnostics reported by Poetry users.
- Add diagnostics for invalid `await` expressions ([#19711](https://github.com/astral-sh/ruff/pull/19711))
- Add `else`-branch narrowing for `if type(a) is A` when `A` is `@final` ([#19925](https://github.com/astral-sh/ruff/pull/19925))
- Improve solving of typevars with defaults, and `typing.Self` ([#19786](https://github.com/astral-sh/ruff/pull/19786))
- Support the `kw_only` parameter for `dataclasses.dataclass()` and `dataclasses.field()` ([#19677](https://github.com/astral-sh/ruff/pull/19677))
- Sync vendored typeshed stubs ([#19923](https://github.com/astral-sh/ruff/pull/19923)). [Typeshed diff](https://github.com/python/typeshed/compare/3f08a4ed10b321c378107c236a06a33584869a9b...893b9a760deb3be64d13c748318e95a752230961).
### Server improvements
- Improve goto/hover for definitions ([#19976](https://github.com/astral-sh/ruff/pull/19976))
### Performance improvements
- Short-circuit a server [inlay hints request](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_inlayHint) if all settings under `ty.inlayHints` are disabled ([#19963](https://github.com/astral-sh/ruff/pull/19963))
- Speedup server tracing checks ([#19965](https://github.com/astral-sh/ruff/pull/19965))
- Add caching to logic for inferring whether a class is a `NamedTuple`, a dataclass or a `TypedDict` ([#19912](https://github.com/astral-sh/ruff/pull/19912))
- Speedup project file discovery ([#19913](https://github.com/astral-sh/ruff/pull/19913))
### Contributors
- [@dcreager](https://github.com/dcreager)
- [@MichaReiser](https://github.com/MichaReiser)
- [@sharkdp](https://github.com/sharkdp)
- [@github-actions](https://github.com/github-actions)
- [@mtshiba](https://github.com/mtshiba)
- [@theammir](https://github.com/theammir)
- [@AlexWaygood](https://github.com/AlexWaygood)
- [@thejchap](https://github.com/thejchap)
- [@Gankra](https://github.com/Gankra)
- [@MatthewMckee4](https://github.com/MatthewMckee4)
- [@carljm](https://github.com/carljm)
## 0.0.1-alpha.18
### Bug fixes
- Fix goto definition on imports ([#19834](https://github.com/astral-sh/ruff/pull/19834))
- Support non-generic recursive type aliases that use [the `type` statement](https://docs.python.org/3/reference/simple_stmts.html#grammar-token-python-grammar-type_stmt) ([#19805](https://github.com/astral-sh/ruff/pull/19805))
- Handle cycles when finding implicit attributes ([#19833](https://github.com/astral-sh/ruff/pull/19833))
### Server
- Implement support for "rename" language server feature ([#19551](https://github.com/astral-sh/ruff/pull/19551))
- Add `ty.experimental.rename` server setting ([#19800](https://github.com/astral-sh/ruff/pull/19800))
- Add `ty.inlayHints.variableTypes` server setting ([#19780](https://github.com/astral-sh/ruff/pull/19780))
- Add inlay hints for call arguments (configured by `ty.inlayHints.callArgumentNames` server setting) ([#19269](https://github.com/astral-sh/ruff/pull/19269))
- Enable goto definition to jump to the runtime definition in the standard library for stdlib symbols (rather than the type definition in typeshed's stubs) ([#19529](https://github.com/astral-sh/ruff/pull/19529))
- Support LSP client settings ([#19614](https://github.com/astral-sh/ruff/pull/19614))
- Update goto range for attribute access to only target the attribute ([#19848](https://github.com/astral-sh/ruff/pull/19848))
- Warn users if the server received unknown options ([#19779](https://github.com/astral-sh/ruff/pull/19779))
- Render docstrings in hover ([#19882](https://github.com/astral-sh/ruff/pull/19882))
- Resolve docstrings for modules ([#19898](https://github.com/astral-sh/ruff/pull/19898))
### Typing semantics and features
- Add precise inference for indexing, slicing and unpacking `NamedTuple` instances ([#19560](https://github.com/astral-sh/ruff/pull/19560))
- Disallow `typing.TypedDict` in type expressions ([#19777](https://github.com/astral-sh/ruff/pull/19777))
- Implement module-level `__getattr__` support ([#19791](https://github.com/astral-sh/ruff/pull/19791))
- Improve ability to solve TypeVars when they appear in unions ([#19829](https://github.com/astral-sh/ruff/pull/19829))
- Improve subscript narrowing for `collections.ChainMap`, `collections.Counter`, `collections.deque` and `collections.OrderedDict` ([#19781](https://github.com/astral-sh/ruff/pull/19781))
- Extend all tuple special casing to tuple subclasses ([#19669](https://github.com/astral-sh/ruff/pull/19669))
- Use separate Rust types for bound and unbound type variables ([#19796](https://github.com/astral-sh/ruff/pull/19796))
- Validate writes to `TypedDict` keys ([#19782](https://github.com/astral-sh/ruff/pull/19782))
- `typing.Self` is bound by the method, not the class ([#19784](https://github.com/astral-sh/ruff/pull/19784))
- Fix deferred name loading in PEP695 generic classes/functions ([#19888](https://github.com/astral-sh/ruff/pull/19888))
- Improve handling of symbol-lookup edge cases involving class scopes ([#19795](https://github.com/astral-sh/ruff/pull/19795))
### Performance
- Improve performance around tuple types ([#19840](https://github.com/astral-sh/ruff/pull/19840))
- Improve performance of subtyping and assignability checks for protocols ([#19824](https://github.com/astral-sh/ruff/pull/19824))
- Improve multithreaded performance for large codebases ([#19867](https://github.com/astral-sh/ruff/pull/19867))
### Memory usage optimizations
- Reduce memory usage of `TupleSpec` and `TupleType` ([#19872](https://github.com/astral-sh/ruff/pull/19872))
- Reduce size of member table ([#19572](https://github.com/astral-sh/ruff/pull/19572))
### Contributors
- [@AlexWaygood](https://github.com/AlexWaygood)
- [@Gankra](https://github.com/Gankra)
- [@ntbre](https://github.com/ntBre)
- [@MichaReiser](https://github.com/MichaReiser)
- [@PrettyWood](https://github.com/PrettyWood)
- [@dhruvmanila](https://github.com/dhruvmanila)
- [@carljm](https://github.com/carljm)
- [@dcreager](https://github.com/dcreager)
- [@UnboundVariable](https://github.com/UnboundVariable)
- [@sharkdp](https://github.com/sharkdp)
- [@oconnor663](https://github.com/oconnor663)
- [@MatthewMckee4](https://github.com/MatthewMckee4)
## 0.0.1-alpha.17
### Bug fixes
- Always refresh diagnostics after a watched files change ([#19697](https://github.com/astral-sh/ruff/pull/19697))
- Correctly instantiate generic class that inherits `__init__` from generic base class ([#19693](https://github.com/astral-sh/ruff/pull/19693))
- Don't panic with argument that doesn't actually implement Iterable ([#19602](https://github.com/astral-sh/ruff/pull/19602))
- Fix "peek definition" in playground ([#19592](https://github.com/astral-sh/ruff/pull/19592))
- Fix empty spans following a line terminator and unprintable character spans in diagnostics ([#19535](https://github.com/astral-sh/ruff/pull/19535))
- Fix incorrect diagnostic when calling `__setitem__` ([#19645](https://github.com/astral-sh/ruff/pull/19645))
- Fix lookup order of class variables before they are defined ([#19743](https://github.com/astral-sh/ruff/pull/19743))
- Fix more false positives related to `Generic` or `Protocol` being subscripted with a `ParamSpec` or `TypeVarTuple` ([#19764](https://github.com/astral-sh/ruff/pull/19764))
- Keep track of type qualifiers in stub declarations without right-hand side ([#19756](https://github.com/astral-sh/ruff/pull/19756))
### Server
- Add progress reporting to workspace diagnostics ([#19616](https://github.com/astral-sh/ruff/pull/19616))
- Add stub mapping support to signature help ([#19570](https://github.com/astral-sh/ruff/pull/19570))
- Added support for "document symbols" and "workspace symbols" ([#19521](https://github.com/astral-sh/ruff/pull/19521))
- Fix server panic in workspace diagnostics request handler when typing ([#19631](https://github.com/astral-sh/ruff/pull/19631))
- Implement caching for workspace and document diagnostics ([#19605](https://github.com/astral-sh/ruff/pull/19605))
- Implement long-polling for workspace diagnostics ([#19670](https://github.com/astral-sh/ruff/pull/19670))
- Implement streaming for workspace diagnostics ([#19657](https://github.com/astral-sh/ruff/pull/19657))
- Implemented support for "selection range" language server feature ([#19567](https://github.com/astral-sh/ruff/pull/19567))
### CLI
- Add progress bar to `--watch` mode ([#19729](https://github.com/astral-sh/ruff/pull/19729))
- Clear the terminal screen in `--watch` mode ([#19712](https://github.com/astral-sh/ruff/pull/19712))
- Resolve file symlinks in src walk ([#19674](https://github.com/astral-sh/ruff/pull/19674))
### Typing semantics and features
- Support `async`/`await`, `async with` and `yield from` ([#19595](https://github.com/astral-sh/ruff/pull/19595))
- Add support for `async for` loops and async iterables ([#19634](https://github.com/astral-sh/ruff/pull/19634))
- Don't include already-bound legacy typevars in function generic context ([#19558](https://github.com/astral-sh/ruff/pull/19558))
- Infer types for key-based access on `TypedDict`s ([#19763](https://github.com/astral-sh/ruff/pull/19763))
- Improve `isinstance()` truthiness analysis for generic types ([#19668](https://github.com/astral-sh/ruff/pull/19668))
- Infer `type[tuple[int, str]]` as the meta-type of `tuple[int, str]` ([#19741](https://github.com/astral-sh/ruff/pull/19741))
- Remove false positives when subscripting `Generic` or `Protocol` with a `ParamSpec` or `TypeVarTuple` ([#19749](https://github.com/astral-sh/ruff/pull/19749))
- Remove special casing for string-literal-in-tuple `__contains__` ([#19642](https://github.com/astral-sh/ruff/pull/19642))
- Remove special casing for tuple addition ([#19636](https://github.com/astral-sh/ruff/pull/19636))
- Return `Option<TupleType>` from `infer_tuple_type_expression` ([#19735](https://github.com/astral-sh/ruff/pull/19735))
- Support `as`-patterns in reachability analysis ([#19728](https://github.com/astral-sh/ruff/pull/19728))
- Support `__setitem__` and improve `__getitem__` related diagnostics ([#19578](https://github.com/astral-sh/ruff/pull/19578))
- Synthesize precise `__getitem__` overloads for tuple subclasses ([#19493](https://github.com/astral-sh/ruff/pull/19493))
- Track different uses of legacy typevars, including context when rendering typevars ([#19604](https://github.com/astral-sh/ruff/pull/19604))
- Upcast heterogeneous and mixed tuples to homogeneous tuples where it's necessary to solve a `TypeVar` ([#19635](https://github.com/astral-sh/ruff/pull/19635))
- Fix incorrect lazy scope narrowing ([#19744](https://github.com/astral-sh/ruff/pull/19744))
- Synthesize `__replace__` for dataclasses ([#19545](https://github.com/astral-sh/ruff/pull/19545))
### Diagnostics
- Add diagnostics for async context managers ([#19704](https://github.com/astral-sh/ruff/pull/19704))
- Display generic function signature properly ([#19544](https://github.com/astral-sh/ruff/pull/19544))
- Improve the `Display` for generic `type[]` types ([#19667](https://github.com/astral-sh/ruff/pull/19667))
- Remap Jupyter notebook cell indices in `ruff_db` ([#19698](https://github.com/astral-sh/ruff/pull/19698))
### Documentation
- Add the `ty` badge ([#897](https://github.com/astral-sh/ty/pull/897))
### Contributors
- [@mtshiba](https://github.com/mtshiba)
- [@MichaReiser](https://github.com/MichaReiser)
- [@sharkdp](https://github.com/sharkdp)
- [@github-actions](https://github.com/github-actions)
- [@UnboundVariable](https://github.com/UnboundVariable)
- [@jorenham](https://github.com/jorenham)
- [@silamon](https://github.com/silamon)
- [@AlexWaygood](https://github.com/AlexWaygood)
- [@thejchap](https://github.com/thejchap)
- [@ngroman](https://github.com/ngroman)
- [@leandrobbraga](https://github.com/leandrobbraga)
- [@dcreager](https://github.com/dcreager)
- [@ntbre](https://github.com/ntBre)
- [@MatthewMckee4](https://github.com/MatthewMckee4)
## 0.0.1-alpha.16
### Bug fixes
- Fix server panics when hovering over invalid syntax in `Callable` annotations ([#19517](https://github.com/astral-sh/ruff/pull/19517))
- `match` statements: Fix narrowing and reachability of class patterns with arguments ([#19512](https://github.com/astral-sh/ruff/pull/19512))
- Fix server panics when hovering over illegal `Literal[…]` annotations with inner subscript expressions ([#19489](https://github.com/astral-sh/ruff/pull/19489))
- Pass down specialization to generic dataclass bases ([#19472](https://github.com/astral-sh/ruff/pull/19472))
### Server
- Add support for "go to definition" for attribute accesses and keyword arguments ([#19417](https://github.com/astral-sh/ruff/pull/19417))
- Add support for "go to definition" for import statements ([#19428](https://github.com/astral-sh/ruff/pull/19428))
- Add support for "document highlights" ([#19515](https://github.com/astral-sh/ruff/pull/19515))
- Add partial support for "find references" ([#19475](https://github.com/astral-sh/ruff/pull/19475))
- Prefer the runtime definition, not the stub definition, on a go-to-definition request for a class or function. Currently this is only implemented for definitions originating outside of the stdlib. ([#19471](https://github.com/astral-sh/ruff/pull/19471))
- Add [semantic token](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_semanticTokens) support for more identifiers ([#19473](https://github.com/astral-sh/ruff/pull/19473))
- Avoid rechecking the entire project when a file in the editor is opened or closed ([#19463](https://github.com/astral-sh/ruff/pull/19463))
### Typing semantics and features
- Handle splatted arguments in function calls ([#18996](https://github.com/astral-sh/ruff/pull/18996))
- Improve place lookup and narrowing in lazy scopes ([#19321](https://github.com/astral-sh/ruff/pull/19321))
- Add exhaustiveness checking and reachability analysis for `match` statements ([#19508](https://github.com/astral-sh/ruff/pull/19508))
- Improve reachability analysis for `isinstance(…)` branches ([#19503](https://github.com/astral-sh/ruff/pull/19503))
- Make tuple subclass constructors sound ([#19469](https://github.com/astral-sh/ruff/pull/19469))
- Extend tuple `__len__` and `__bool__` special casing to also cover tuple subclasses ([#19289](https://github.com/astral-sh/ruff/pull/19289))
- Add support for `dataclasses.field` ([#19553](https://github.com/astral-sh/ruff/pull/19553))
- Add support for `dataclasses.InitVar` ([#19527](https://github.com/astral-sh/ruff/pull/19527))
- Add support for `@warnings.deprecated` and `typing_extensions.deprecated` ([#19376](https://github.com/astral-sh/ruff/pull/19376))
- Do not consider a type `T` to satisfy a method member on a protocol unless the method is available on the meta-type of `T` ([#19187](https://github.com/astral-sh/ruff/pull/19187))
- Implement expansion of enums into unions of literals ([#19382](https://github.com/astral-sh/ruff/pull/19382))
- Support iterating over enums ([#19486](https://github.com/astral-sh/ruff/pull/19486))
- Detect enums if metaclass is a subtype of `EnumType` / `EnumMeta` ([#19481](https://github.com/astral-sh/ruff/pull/19481))
- Infer single-valuedness for enums deriving from `int` or `str` ([#19510](https://github.com/astral-sh/ruff/pull/19510))
- Detect illegal non-enum attribute accesses in `Literal` annotations ([#19477](https://github.com/astral-sh/ruff/pull/19477))
- Disallow assignment to `Final` class attributes ([#19457](https://github.com/astral-sh/ruff/pull/19457))
- Handle implicit instance attributes declared `Final` ([#19462](https://github.com/astral-sh/ruff/pull/19462))
- Disallow `Final` in function parameter- and return-type annotations ([#19480](https://github.com/astral-sh/ruff/pull/19480))
- Disallow illegal uses of `ClassVar` ([#19483](https://github.com/astral-sh/ruff/pull/19483))
- Make `del x` force a local resolution of `x` in the current scope ([#19389](https://github.com/astral-sh/ruff/pull/19389))
- Perform type narrowing for places marked `global` ([#19381](https://github.com/astral-sh/ruff/pull/19381))
- Infer correct types for attribute accesses on intersections with negative parts ([#19524](https://github.com/astral-sh/ruff/pull/19524))
- Sync vendored typeshed stubs ([typeshed diff](https://github.com/python/typeshed/compare/84e41f2853d7af3d651d620f093031cba849bd1d...08225953c98cfd375d80bc88865e5aae77d2c07f))
### Memory usage optimizations
- Reduce ty's memory usage (for example: [#19409](https://github.com/astral-sh/ruff/pull/19409), [#19435](https://github.com/astral-sh/ruff/pull/19435), [#19414](https://github.com/astral-sh/ruff/pull/19414))
### Contributors
- [@sharkdp](https://github.com/sharkdp)
- [@BurntSushi](https://github.com/BurntSushi)
- [@oconnor663](https://github.com/oconnor663)
- [@Gankra](https://github.com/Gankra)
- [@carljm](https://github.com/carljm)
- [@AlexWaygood](https://github.com/AlexWaygood)
- [@MichaReiser](https://github.com/MichaReiser)
- [@dcreager](https://github.com/dcreager)
- [@mtshiba](https://github.com/mtshiba)
- [@UnboundVariable](https://github.com/UnboundVariable)
## 0.0.1-alpha.15
### Bug fixes
- Avoid stale diagnostics for open-files diagnostic mode ([#19273](https://github.com/astral-sh/ruff/pull/19273))
- Fix inconsistent semantic syntax highlighting for parameters ([#19418](https://github.com/astral-sh/ruff/pull/19418))
- Fix checking of virtual files after re-opening from an unsaved edit ([#19277](https://github.com/astral-sh/ruff/pull/19277))
- Show the correct ty version in the LSP server ([#19284](https://github.com/astral-sh/ruff/pull/19284))
- Do not surface settings errors in unrelated Python files ([#19206](https://github.com/astral-sh/ruff/pull/19206))
- Do not ignore conditionally defined dataclass fields ([#19197](https://github.com/astral-sh/ruff/pull/19197))
- Fix panic for attribute expressions with empty value ([#19069](https://github.com/astral-sh/ruff/pull/19069))
- Fix assignabiliy of dataclasses to `Callable` types ([#19192](https://github.com/astral-sh/ruff/pull/19192))
- Fix `__setattr__` call check precedence during attribute assignment ([#18347](https://github.com/astral-sh/ruff/pull/18347))
### Server
- Add definition and declaration providers (go-to-definition, go-to-declaration) ([#19371](https://github.com/astral-sh/ruff/pull/19371))
- Add signature help provider (show signature and docstring when writing a call expression) ([#19194](https://github.com/astral-sh/ruff/pull/19194))
- Add "kind" to completion suggestions ([#19216](https://github.com/astral-sh/ruff/pull/19216))
- Add completions for submodules that aren't attributes of their parent ([#19266](https://github.com/astral-sh/ruff/pull/19266))
- Filter out private type aliases from stub files when offering autocomplete suggestions ([#19282](https://github.com/astral-sh/ruff/pull/19282))
- Handle configuration errors in the LSP more gracefully ([#19262](https://github.com/astral-sh/ruff/pull/19262))
- Use Python version and path from VSCode Python extension ([#19012](https://github.com/astral-sh/ruff/pull/19012))
- Publish errors in settings as LSP diagnostics ([#19335](https://github.com/astral-sh/ruff/pull/19335))
### Typing semantics and features
- Add support for `nonlocal` statements ([#19112](https://github.com/astral-sh/ruff/pull/19112))
- Support empty function bodies in `if TYPE_CHECKING` blocks ([#19372](https://github.com/astral-sh/ruff/pull/19372))
- Emit a diagnostic when attempting to modify a `typing.Final`-qualified symbol ([#19178](https://github.com/astral-sh/ruff/pull/19178))
- Infer enum literal types when accessing enum members ([#19328](https://github.com/astral-sh/ruff/pull/19328))
- Synthesize `__setattr__` for frozen dataclasses ([#19307](https://github.com/astral-sh/ruff/pull/19307))
- Improve equivalence for module-literal types ([#19243](https://github.com/astral-sh/ruff/pull/19243))
- Reduce false positives for `TypedDict` types ([#19354](https://github.com/astral-sh/ruff/pull/19354))
- Emit an error for `global` uses if there is no explicit definition in the global scope ([#19344](https://github.com/astral-sh/ruff/pull/19344))
- Sync vendored typeshed stubs ([typeshed diff](https://github.com/python/typeshed/compare/f64707592dd3c32f756ddeebd012acb2b072aa0d...84e41f2853d7af3d651d620f093031cba849bd1d))
### CLI
- Add a `-q`/`--quiet` mode, `-qq` for silent output mode ([#19233](https://github.com/astral-sh/ruff/pull/19233))
### Contributors
- [@AlexWaygood](https://github.com/AlexWaygood)
- [@github-actions](https://github.com/github-actions)
- [@dhruvmanila](https://github.com/dhruvmanila)
- [@sharkdp](https://github.com/sharkdp)
- [@renovate](https://github.com/renovate)
- [@MatthewMckee4](https://github.com/MatthewMckee4)
- [@UnboundVariable](https://github.com/UnboundVariable)
- [@oconnor663](https://github.com/oconnor663)
- [@zanieb](https://github.com/zanieb)
- [@MichaReiser](https://github.com/MichaReiser)
- [@charliermarsh](https://github.com/charliermarsh)
- [@Gankra](https://github.com/Gankra)
- [@thejchap](https://github.com/thejchap)
- [@BurntSushi](https://github.com/BurntSushi)
- [@mdqst](https://github.com/mdqst)
## 0.0.1-alpha.14
### Bug fixes
- Add cycle detection to ty's implementation of disjointness between types, fixing a possible source of stack overflows when analysing recursive types ([#19139](https://github.com/astral-sh/ruff/pull/19139))
- Don't allow first-party code to shadow the stdlib `types` module ([#19128](https://github.com/astral-sh/ruff/pull/19128)).
This fixes another possible source of stack overflows.
- Fix descriptor lookups for most types that overlap with `None` ([#19120](https://github.com/astral-sh/ruff/pull/19120)).
This means that e.g. `object().__str__()` now correctly binds the `self` argument of the `__str__`
method, as the `object` type overlaps with `None`.
### Server
- Filter a symbol from a stub file in autocomplete suggestions if it is an implementation detail of the stub ([#19121](https://github.com/astral-sh/ruff/pull/19121))
- Add initial support for [semantic tokens](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_semanticTokens) ([#19108](https://github.com/astral-sh/ruff/pull/19108)).
This feature allows editors to apply more advanced syntax highlighting. Currently, the supported tokens are: `Namespace`, `Class`, `Parameter`, `SelfParameter`,`ClsParameter`, `Variable`, `Property`, `Function`, `Method`, `Keyword`, `String`, `Number`, `Decorator`, `BuiltinConstant` and `TypeParameter`.
- Initial support for [workspace diagnostics](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#workspace_diagnostic) ([#18939](https://github.com/astral-sh/ruff/pull/18939)).
Enable this feature by setting the `ty.diagnosticMode` configuration setting to `"workspace"`.
- Use Python syntax highlighting in on-hover content ([#19082](https://github.com/astral-sh/ruff/pull/19082))
### Typing semantics and features
- Understand that calls to functions returning `Never` / `NoReturn` are terminal with respect to control flow ([#18333](https://github.com/astral-sh/ruff/pull/18333))
- Add subtyping between `type[]` types and `Callable` types ([#19026](https://github.com/astral-sh/ruff/pull/19026))
- Support bare `ClassVar` annotations ([#15768](https://github.com/astral-sh/ruff/pull/15768))
- Understand that two protocols with equivalent method members are equivalent ([#18659](https://github.com/astral-sh/ruff/pull/18659))
- Support declared-only instance attributes such as `self.x: int` ([#19048](https://github.com/astral-sh/ruff/pull/19048))
- Sync vendored typeshed stubs ([#19174](https://github.com/astral-sh/ruff/pull/19174)): [typeshed diff](https://github.com/python/typeshed/compare/3f727b0cd6620b7fca45318dd34542b1e1c7dbfb...f64707592dd3c32f756ddeebd012acb2b072aa0d)
- Use the inferred type as the declared type for bare `Final` symbols ([#19142](https://github.com/astral-sh/ruff/pull/19142))
### Contributors
- [@iyakushev](https://github.com/iyakushev)
- [@MatthewMckee4](https://github.com/MatthewMckee4)
- [@zanieb](https://github.com/zanieb)
- [@sharkdp](https://github.com/sharkdp)
- [@UnboundVariable](https://github.com/UnboundVariable)
- [@abhijeetbodas2001](https://github.com/abhijeetbodas2001)
- [@github-actions](https://github.com/github-actions)
- [@dhruvmanila](https://github.com/dhruvmanila)
- [@AlexWaygood](https://github.com/AlexWaygood)
- [@carljm](https://github.com/carljm)
- [@CodeMan62](https://github.com/CodeMan62)
## 0.0.1-alpha.13
### Bug fixes
- Fix stack overflows related to mutually recursive protocols ([#19003](https://github.com/astral-sh/ruff/pull/19003))
- Don't add incorrect subdiagnostic for `unresolved-reference` in `staticmethod`s and `classmethod`s ([#18487](https://github.com/astral-sh/ruff/pull/18487))
- Fix rendering of long lines in diagnostic messages that are indented with tabs ([#18962](https://github.com/astral-sh/ruff/pull/18962))
- Fix reachability of star import definitions for nonlocal lookups ([#19066](https://github.com/astral-sh/ruff/pull/19066))
### Typing semantics and features
- Support variable-length tuples in unpacking assignments ([#18948](https://github.com/astral-sh/ruff/pull/18948))
- Allow declared-only class-level attributes to be accessed on the class ([#19071](https://github.com/astral-sh/ruff/pull/19071))
- Infer nonlocal types as unions of all reachable bindings ([#18750](https://github.com/astral-sh/ruff/pull/18750))
- Use all reachable bindings for instance attributes and deferred lookups ([#18955](https://github.com/astral-sh/ruff/pull/18955))
- Improve protocol member type checking and relation handling ([#18847](https://github.com/astral-sh/ruff/pull/18847))
- Rework disjointness of protocol instances vs types with possibly unbound attributes, preventing some false instances of `Never` in `hasattr` narrowing ([#19043](https://github.com/astral-sh/ruff/pull/19043))
- Make tuple instantiations sound ([#18987](https://github.com/astral-sh/ruff/pull/18987))
- Add subdiagnostic about empty bodies in more cases ([#18942](https://github.com/astral-sh/ruff/pull/18942))
- Improve type-inference for `__import__(name)` and `importlib.import_module(name)` ([#19008](https://github.com/astral-sh/ruff/pull/19008))
- Eagerly evaluate certain constraints when analyzing control flow ([#18998](https://github.com/astral-sh/ruff/pull/18998), [#19044](https://github.com/astral-sh/ruff/pull/19044), [#19068](https://github.com/astral-sh/ruff/pull/19068))
- Update typeshed stubs ([#19060](https://github.com/astral-sh/ruff/pull/19060)): [typeshed diff](https://github.com/python/typeshed/compare/ecd5141cc036366cc9e3ca371096d6a14b0ccd13...3f727b0cd6620b7fca45318dd34542b1e1c7dbfb)
### Server
- Add `builtins` to completions ([#18982](https://github.com/astral-sh/ruff/pull/18982))
- Support LSP go-to with vendored typeshed stubs ([#19057](https://github.com/astral-sh/ruff/pull/19057))
### Documentation
- The ty documentation is now available at [docs.astral.sh/ty](https://docs.astral.sh/ty) ([#744](https://github.com/astral-sh/ty/pull/744))
### Performance
- Remove `ScopedExpressionId` ([#19019](https://github.com/astral-sh/ruff/pull/19019))
### Contributors
- [@InSyncWithFoo](https://github.com/InSyncWithFoo)
- [@MatthewMckee4](https://github.com/MatthewMckee4)
- [@dcreager](https://github.com/dcreager)
- [@mtshiba](https://github.com/mtshiba)
- [@BurntSushi](https://github.com/BurntSushi)
- [@sharkdp](https://github.com/sharkdp)
- [@ibraheemdev](https://github.com/ibraheemdev)
- [@github-actions](https://github.com/github-actions)
- [@carljm](https://github.com/carljm)
- [@AlexWaygood](https://github.com/AlexWaygood)
- [@MichaReiser](https://github.com/MichaReiser)
- [@zanieb](https://github.com/zanieb)
## 0.0.1-alpha.12
### Bug fixes
- Avoid duplicate diagnostic when reporting errors in unpacked assignments ([#18897](https://github.com/astral-sh/ruff/pull/18897))
- Fix panics when "pulling types" for `ClassVar` or `Final` parameterized with >1 argument ([#18824](https://github.com/astral-sh/ruff/pull/18824)). These could cause issues when hovering over symbols in an IDE.
### Improved modeling of Python runtime semantics
- Add support for `@staticmethod`s ([#18809](https://github.com/astral-sh/ruff/pull/18809))
- Discover implicit class attribute assignments in `@classmethod`-decorated methods. Recognize that assignments in the body of a `@staticmethod`-decorated method are never instance attributes ([#18587](https://github.com/astral-sh/ruff/pull/18587))
- Report when a dataclass contains more than one `KW_ONLY` field ([#18731](https://github.com/astral-sh/ruff/pull/18731))
### Type narrowing improvements
- Ty will now perform `isinstance()` and `issubclass()` narrowing when the second argument is a union type, intersection type or `TypeVar` type ([#18900](https://github.com/astral-sh/ruff/pull/18900))
- Ty now narrows types in comprehensions and generator expressions ([#18934](https://github.com/astral-sh/ruff/pull/18934))
- Understand two `NominalInstanceType`s as disjoint types if attempting to use multiple inheritance with their underlying classes would result in an instance memory layout conflict ([#18864](https://github.com/astral-sh/ruff/pull/18864))
### Other typing semantics features
- Support "mixed" tuples such as `tuple[int, *tuple[str, ...]]` ([#18600](https://github.com/astral-sh/ruff/pull/18600), [#18901](https://github.com/astral-sh/ruff/pull/18901))
- Support type inference for subscript expressions on union types ([#18846](https://github.com/astral-sh/ruff/pull/18846))
- Introduce a new subtyping framework in which gradual types can participate, allowing for more advanced union type simplification ([#18799](https://github.com/astral-sh/ruff/pull/18799))
- Surface the matched overload directly when reporting a diagnostic for an invalid call to an overloaded function ([#18452](https://github.com/astral-sh/ruff/pull/18452))
### Improvements to server autocompletions
- Add completions for `from module import <CURSOR>` ([#18830](https://github.com/astral-sh/ruff/pull/18830))
- Enforce sort order of completions ([#18917](https://github.com/astral-sh/ruff/pull/18917))
- Include imported sub-modules as attributes on modules for completions ([#18898](https://github.com/astral-sh/ruff/pull/18898))
### Configuration
- Anchor all `src.exclude` patterns, for consistency with `src.include` patterns ([#18685](https://github.com/astral-sh/ruff/pull/18685))
- Change `environment.root` to accept multiple paths ([#18913](https://github.com/astral-sh/ruff/pull/18913))
- Rename `src.root` setting to `environment.root` ([#18760](https://github.com/astral-sh/ruff/pull/18760))
- Support `--python=<symlink to executable>` ([#18827](https://github.com/astral-sh/ruff/pull/18827))
### Contributors
- [@BurntSushi](https://github.com/BurntSushi)
- [@InSyncWithFoo](https://github.com/InSyncWithFoo)
- [@suneettipirneni](https://github.com/suneettipirneni)
- [@AlexWaygood](https://github.com/AlexWaygood)
- [@dhruvmanila](https://github.com/dhruvmanila)
- [@sharkdp](https://github.com/sharkdp)
- [@MichaReiser](https://github.com/MichaReiser)
- [@med1844](https://github.com/med1844)
- [@dcreager](https://github.com/dcreager)
- [@carljm](https://github.com/carljm)
## 0.0.1-alpha.11
### Breaking changes
- Stabilize auto-complete; remove the opt-in experimental setting ([#18650](https://github.com/astral-sh/ruff/pull/18650))
### Bug fixes
- Fix binary expression inference between Boolean literals and `bool` instances ([#18663](https://github.com/astral-sh/ruff/pull/18663))
- Fix panic that could occur when printing a class's "header" in diagnostic messages ([#18670](https://github.com/astral-sh/ruff/pull/18670))
- Fix panic when attempting to provide autocompletions for an instance of a class that assigns attributes to `self[0]` ([#18707](https://github.com/astral-sh/ruff/pull/18707))
- Fix panics when "pulling types" for various special forms that have the wrong number of parameters. These could cause issues when hovering over symbols in an IDE. ([#18642](https://github.com/astral-sh/ruff/pull/18642))
### Typing semantics and features
- Support type narrowing for attribute and subscript expressions ([#17643](https://github.com/astral-sh/ruff/pull/17643))
- Add partial support for `TypeIs` ([#18589](https://github.com/astral-sh/ruff/pull/18589))
- Support `dataclasses.KW_ONLY` ([#18677](https://github.com/astral-sh/ruff/pull/18677))
- Filter overloads based on `Any` / `Unknown` ([#18607](https://github.com/astral-sh/ruff/pull/18607))
- Improve reachability analysis ([#18621](https://github.com/astral-sh/ruff/pull/18621))
- Model `T: Never` as a subtype of `Never` ([#18687](https://github.com/astral-sh/ruff/pull/18687))
- Update typeshed stubs ([#18679](https://github.com/astral-sh/ruff/pull/18679)): [typeshed diff](https://github.com/python/typeshed/compare/5a3c495d2f6fa9b68cd99f39feba4426e4d17ea9...ecd5141cc036366cc9e3ca371096d6a14b0ccd13)
### Configuration
- Allow overriding rules for specific files ([#18648](https://github.com/astral-sh/ruff/pull/18648))
### Server
- Add `python.ty.disableLanguageServices` config ([#18230](https://github.com/astral-sh/ruff/pull/18230))
### Contributors
- [@dhruvmanila](https://github.com/dhruvmanila)
- [@felixscherz](https://github.com/felixscherz)
- [@MichaReiser](https://github.com/MichaReiser)
- [@alpaylan](https://github.com/alpaylan)
- [@mtshiba](https://github.com/mtshiba)
- [@github-actions](https://github.com/github-actions)
- [@BurntSushi](https://github.com/BurntSushi)
- [@InSyncWithFoo](https://github.com/InSyncWithFoo)
- [@AlexWaygood](https://github.com/AlexWaygood)
- [@abhijeetbodas2001](https://github.com/abhijeetbodas2001)
- [@sharkdp](https://github.com/sharkdp)
- [@ibraheemdev](https://github.com/ibraheemdev)
## 0.0.1-alpha.10
### Server
- Improve support for `object.<CURSOR>` completions ([#18629](https://github.com/astral-sh/ruff/pull/18629))
### Configuration
- Add file inclusion and exclusion ([#18498](https://github.com/astral-sh/ruff/pull/18498))
- Infer the Python version from `--python=<system installation>` on Unix ([#18550](https://github.com/astral-sh/ruff/pull/18550))
### Bug fixes
- Delay computation of 'unbound' visibility for implicit instance attributes ([#18669](https://github.com/astral-sh/ruff/pull/18669)).
This fixes a significant performance regression in version 0.0.1-alpha.9.
### Typing semantics and features
- Support the `del` statement; model implicit deletion of except handler names ([#18593](https://github.com/astral-sh/ruff/pull/18593))
### Release
- Include ruff/ directory in release source tarballs ([#617](https://github.com/astral-sh/ty/pull/617))
### Contributors
- [@AlexWaygood](https://github.com/AlexWaygood)
- [@BurntSushi](https://github.com/BurntSushi)
- [@Gankra](https://github.com/Gankra)
- [@mtshiba](https://github.com/mtshiba)
- [@sharkdp](https://github.com/sharkdp)
- [@dhruvmanila](https://github.com/dhruvmanila)
- [@MichaReiser](https://github.com/MichaReiser)
## 0.0.1-alpha.9
### Typing semantics and features
- Add generic inference for dataclasses ([#18443](https://github.com/astral-sh/ruff/pull/18443))
- Add support for global `__debug__` constant ([#18540](https://github.com/astral-sh/ruff/pull/18540))
- Argument type expansion for overload call evaluation ([#18382](https://github.com/astral-sh/ruff/pull/18382))
- Exclude members starting with `_abc_` from a protocol interface ([#18467](https://github.com/astral-sh/ruff/pull/18467))
- Infer `list[T]` for starred target in unpacking ([#18401](https://github.com/astral-sh/ruff/pull/18401))
- Infer `list[T]` when unpacking non-tuple type ([#18438](https://github.com/astral-sh/ruff/pull/18438))
- Support type annotation for legacy typing aliases for generic classes ([#18404](https://github.com/astral-sh/ruff/pull/18404))
- Allow using `dataclasses.dataclass` as a function ([#18440](https://github.com/astral-sh/ruff/pull/18440))
- Type narrowing for attribute/subscript assignments ([#18041](https://github.com/astral-sh/ruff/pull/18041))
### Diagnostics
- Add hints to `invalid-type-form` for common mistakes ([#18543](https://github.com/astral-sh/ruff/pull/18543))
- Add subdiagnostic suggestion to `unresolved-reference` diagnostic when variable exists on `self` ([#18444](https://github.com/astral-sh/ruff/pull/18444))
- Track the origin of the `environment.python` setting for better error messages ([#18483](https://github.com/astral-sh/ruff/pull/18483))
### CLI
- Fix `--python` argument for Windows, and improve error messages for bad `--python` arguments ([#18457](https://github.com/astral-sh/ruff/pull/18457))
### Bug fixes
- Meta-type of type variables should be `type[..]` ([#18439](https://github.com/astral-sh/ruff/pull/18439))
- Only consider a type `T` a subtype of a protocol `P` if all of `P`'s members are fully bound on `T` ([#18466](https://github.com/astral-sh/ruff/pull/18466))
- Fix false positives for legacy `ParamSpec`s inside `Callable` type expressions ([#18426](https://github.com/astral-sh/ruff/pull/18426))
- Fix panic when pulling types for `UnaryOp` expressions inside `Literal` slices ([#18536](https://github.com/astral-sh/ruff/pull/18536))
- Fix panic when trying to pull types for attribute expressions inside `Literal` type expressions ([#18535](https://github.com/astral-sh/ruff/pull/18535))
- Fix panic when trying to pull types for subscript expressions inside `Callable` type expressions ([#18534](https://github.com/astral-sh/ruff/pull/18534))
- Treat lambda functions as instances of `types.FunctionType` ([#18431](https://github.com/astral-sh/ruff/pull/18431))
- Implement disjointness between `Callable` and `SpecialForm` ([#18503](https://github.com/astral-sh/ruff/pull/18503))
### Server
- Fix stale diagnostics in documents on Windows ([#18544](https://github.com/astral-sh/ruff/pull/18544))
- Add support for `object.<CURSOR>` completions ([#18468](https://github.com/astral-sh/ruff/pull/18468))
- Only provide declarations and bindings as completions ([#18456](https://github.com/astral-sh/ruff/pull/18456))
### Documentation
- Add `CONDA_PREFIX` to `--python` documentation ([#18574](https://github.com/astral-sh/ruff/pull/18574))
- Update list of referenced environment variables ([#612](https://github.com/astral-sh/ty/pull/612))
- Document how the default value for `python-version` is determined ([#18549](https://github.com/astral-sh/ruff/pull/18549))
- Document the `"all"` option for `python-platform` ([#18548](https://github.com/astral-sh/ruff/pull/18548))
### Contributors
- [@AlexWaygood](https://github.com/AlexWaygood)
- [@charliermarsh](https://github.com/charliermarsh)
- [@mtshiba](https://github.com/mtshiba)
- [@benbaror](https://github.com/benbaror)
- [@sharkdp](https://github.com/sharkdp)
- [@carljm](https://github.com/carljm)
- [@MichaReiser](https://github.com/MichaReiser)
- [@lipefree](https://github.com/lipefree)
- [@BurntSushi](https://github.com/BurntSushi)
- [@DetachHead](https://github.com/DetachHead)
- [@MatthewMckee4](https://github.com/MatthewMckee4)
- [@suneettipirneni](https://github.com/suneettipirneni)
- [@abhijeetbodas2001](https://github.com/abhijeetbodas2001)
- [@ibraheemdev](https://github.com/ibraheemdev)
- [@dhruvmanila](https://github.com/dhruvmanila)
## 0.0.1-alpha.8
### Typing semantics and features
- Add subtyping between Callable types and class literals with `__init__` ([#17638](https://github.com/astral-sh/ruff/pull/17638))
- Implement implicit inheritance from `Generic[]` for PEP-695 generic classes ([#18283](https://github.com/astral-sh/ruff/pull/18283))
- Infer the Python version from the environment if feasible ([#18057](https://github.com/astral-sh/ruff/pull/18057))
- Support ephemeral uv virtual environments ([#18335](https://github.com/astral-sh/ruff/pull/18335))
- Model that some `Callable` types should have all `FunctionType` attributes available ([#18242](https://github.com/astral-sh/ruff/pull/18242))
### Diagnostics
- Add diagnostic hints for a function that has a non-`None` return-type annotation but no return statements ([#18359](https://github.com/astral-sh/ruff/pull/18359))
- Add hint if async context manager is used in non-async with statement ([#18299](https://github.com/astral-sh/ruff/pull/18299))
- Improve diagnostics if the user attempts to import a stdlib module that does not exist on their configured Python version ([#18403](https://github.com/astral-sh/ruff/pull/18403))
- Tell the user why we inferred a certain Python version when reporting version-specific syntax errors ([#18295](https://github.com/astral-sh/ruff/pull/18295))
### Bug fixes
- Fix multithreading related hangs and panics ([#18238](https://github.com/astral-sh/ruff/pull/18238))
- Ensure `Literal` types are considered assignable to anything their `Instance` supertypes are assignable to ([#18351](https://github.com/astral-sh/ruff/pull/18351))
- Callable types are disjoint from non-callable `@final` nominal instance types ([#18368](https://github.com/astral-sh/ruff/pull/18368))
- Support callability of bound/constrained typevars ([#18389](https://github.com/astral-sh/ruff/pull/18389))
### Server
- Fix server hang after shutdown request ([#18414](https://github.com/astral-sh/ruff/pull/18414))
- Improve completions by leveraging scopes ([#18281](https://github.com/astral-sh/ruff/pull/18281))
- Support cancellation and retry in the server ([#18273](https://github.com/astral-sh/ruff/pull/18273))
- Support publishing diagnostics in the server ([#18309](https://github.com/astral-sh/ruff/pull/18309))
### CLI
- Add `--config-file` CLI arg ([#18083](https://github.com/astral-sh/ruff/pull/18083))
### Contributors
- [@AlexWaygood](https://github.com/AlexWaygood)
- [@BurntSushi](https://github.com/BurntSushi)
- [@lipefree](https://github.com/lipefree)
- [@MatthewMckee4](https://github.com/MatthewMckee4)
- [@dhruvmanila](https://github.com/dhruvmanila)
- [@zanieb](https://github.com/zanieb)
- [@carljm](https://github.com/carljm)
- [@thejchap](https://github.com/thejchap)
- [@sharkdp](https://github.com/sharkdp)
- [@InSyncWithFoo](https://github.com/InSyncWithFoo)
- [@MichaReiser](https://github.com/MichaReiser)
## 0.0.1-alpha.7
### Bug fixes
- Implement Python's floor-division semantics for `Literal` `int`s ([#18249](https://github.com/astral-sh/ruff/pull/18249))
- Don't warn about a `yield` expression not being in a function if the `yield` expression is in a function ([#18008](https://github.com/astral-sh/ruff/pull/18008))
- Fix inference of attribute writes to unions/intersections that including module-literal types ([#18313](https://github.com/astral-sh/ruff/pull/18313))
- Fix false-positive diagnostics in binary comparison inference logic for intersection types ([#18266](https://github.com/astral-sh/ruff/pull/18266))
- Fix instance vs callable subtyping/assignability ([#18260](https://github.com/astral-sh/ruff/pull/18260))
- Ignore `ClassVar` declarations when resolving instance members ([#18241](https://github.com/astral-sh/ruff/pull/18241))
- Fix crash when hovering over a `ty_extensions.Intersection[A, B]` expression in an IDE context ([#18321](https://github.com/astral-sh/ruff/pull/18321))
- Respect `MRO_NO_OBJECT_FALLBACK` policy when looking up symbols on `type` instances ([#18312](https://github.com/astral-sh/ruff/pull/18312))
- `get_protocol_members` returns a frozenset, not a tuple ([#18284](https://github.com/astral-sh/ruff/pull/18284))
### Typing semantics and features
- Support `import <namespace>` and `from <namespace> import module` ([#18137](https://github.com/astral-sh/ruff/pull/18137))
- Support frozen dataclasses ([#17974](https://github.com/astral-sh/ruff/pull/17974))
- Understand that the presence of a `__getattribute__` method indicates arbitrary members can exist on a type ([#18280](https://github.com/astral-sh/ruff/pull/18280))
- Add a subdiagnostic if `invalid-return-type` is emitted on a method with an empty body on a non-protocol subclass of a protocol class ([#18243](https://github.com/astral-sh/ruff/pull/18243))
- Improve `invalid-type-form` diagnostic where a module-literal type is used in a type expression and the module has a member which would be valid in a type expression ([#18244](https://github.com/astral-sh/ruff/pull/18244))
- Split `invalid-base` error code into two error codes ([#18245](https://github.com/astral-sh/ruff/pull/18245))
- Rename `call-possibly-unbound-method` to `possibly-unbound-implicit-call` ([#18017](https://github.com/astral-sh/ruff/pull/18017))
### Configuration
- Add `tests` to `src.root` by default if a `tests/` directory exists and is not a package ([#18286](https://github.com/astral-sh/ruff/pull/18286))
- Tell the user why we inferred the Python version we inferred ([#18082](https://github.com/astral-sh/ruff/pull/18082))
- Add support for detecting activated Conda and Pixi environments ([#18267](https://github.com/astral-sh/ruff/pull/18267))
- Move `respect-ignore-files` configuration setting under `src` section ([#18322](https://github.com/astral-sh/ruff/pull/18322))
### Server
- Fix server panic when calling `system_mut` ([#18252](https://github.com/astral-sh/ruff/pull/18252))
- Abort process if worker thread panics ([#18211](https://github.com/astral-sh/ruff/pull/18211))
- Gracefully handle salsa cancellations and panics in background request handlers ([#18254](https://github.com/astral-sh/ruff/pull/18254))
### Contributors
- [@felixscherz](https://github.com/felixscherz)
- [@carljm](https://github.com/carljm)
- [@j178](https://github.com/j178)
- [@thejchap](https://github.com/thejchap)
- [@brainwane](https://github.com/brainwane)
- [@AlexWaygood](https://github.com/AlexWaygood)
- [@lipefree](https://github.com/lipefree)
- [@InSyncWithFoo](https://github.com/InSyncWithFoo)
- [@brandtbucher](https://github.com/brandtbucher)
- [@MichaReiser](https://github.com/MichaReiser)
- [@maxmynter](https://github.com/maxmynter)
- [@fabridamicelli](https://github.com/fabridamicelli)
- [@sharkdp](https://github.com/sharkdp)
## 0.0.1-alpha.6
### Server
- Add rule link to server diagnostics ([#18128](https://github.com/astral-sh/ruff/pull/18128))
- Avoid panicking when there are multiple workspaces ([#18151](https://github.com/astral-sh/ruff/pull/18151))
- Show related information in diagnostic ([#17359](https://github.com/astral-sh/ruff/pull/17359))
### Configuration
- Default `src.root` setting to `['.', '<project_name>']` if an `src/` directory does not exist but a `<project-name>/<project-name>` directory does exist ([#18141](https://github.com/astral-sh/ruff/pull/18141))
### Typing semantics and features
- Consider a class with a dynamic element in its MRO assignable to any subtype of `type` ([#18205](https://github.com/astral-sh/ruff/pull/18205))
- Ensure that a function-literal type is always considered equivalent to itself ([#18227](https://github.com/astral-sh/ruff/pull/18227))
- Promote literals when inferring class specializations from constructors ([#18102](https://github.com/astral-sh/ruff/pull/18102))
- Support `typing.TypeAliasType` ([#18156](https://github.com/astral-sh/ruff/pull/18156))
- Infer function-call type variables in both directions ([#18155](https://github.com/astral-sh/ruff/pull/18155))
### Improvements to modeling of runtime semantics
- Integer indexing into `bytes` returns `int` ([#18218](https://github.com/astral-sh/ruff/pull/18218))
- Emit `invalid-exception-caught` diagnostics even when the caught exception is not bound to a variable ([#18202](https://github.com/astral-sh/ruff/pull/18202))
### Usability improvements
- Add hint to some diagnostics that [PEP 604](https://peps.python.org/pep-0604/) union syntax is only available on Python 3.10+ ([#18192](https://github.com/astral-sh/ruff/pull/18192))
- Add note to `unresolved-import` diagnostic hinting to users to configure their Python environment ([#18207](https://github.com/astral-sh/ruff/pull/18207))
- Make `division-by-zero` an opt-in diagnostic rather than opt-out ([#18220](https://github.com/astral-sh/ruff/pull/18220))
### Import resolution improvements
- Add support for PyPy virtual environments ([#18203](https://github.com/astral-sh/ruff/pull/18203))
### Contributors
- [@dhruvmanila](https://github.com/dhruvmanila)
- [@InSyncWithFoo](https://github.com/InSyncWithFoo)
- [@AlexWaygood](https://github.com/AlexWaygood)
- [@MichaReiser](https://github.com/MichaReiser)
- [@BradonZhang](https://github.com/BradonZhang)
- [@dcreager](https://github.com/dcreager)
- [@danielhollas](https://github.com/danielhollas)
- [@esadek](https://github.com/esadek)
- [@kiran-4444](https://github.com/kiran-4444)
- [@Mathemmagician](https://github.com/Mathemmagician)
- [@sharkdp](https://github.com/sharkdp)
- [@felixscherz](https://github.com/felixscherz)
- [@adamaaronson](https://github.com/adamaaronson)
- [@carljm](https://github.com/carljm)
## 0.0.1-alpha.5
### Bug fixes
- Fix assignability checks for invariant generics parameterized by gradual types ([#18138](https://github.com/astral-sh/ruff/pull/18138))
- Revert boolean expression control flow change which caused a performance regression ([#18150](https://github.com/astral-sh/ruff/pull/18150))
- Remove pyvenv.cfg validation check for lines with multiple `=` ([#18144](https://github.com/astral-sh/ruff/pull/18144))
### Contributors
- [@MatthewMckee4](https://github.com/MatthewMckee4)
- [@AlexWaygood](https://github.com/AlexWaygood)
## 0.0.1-alpha.4
### Enhancements
- Allow unions including `Any`/`Unknown` as bases ([#18094](https://github.com/astral-sh/ruff/pull/18094))
- Better control flow for boolean expressions that are inside if ([#18010](https://github.com/astral-sh/ruff/pull/18010))
- Improve invalid method calls for unmatched overloads ([#18122](https://github.com/astral-sh/ruff/pull/18122))
- Add support for `NamedTuple` 'fallback' attributes ([#18127](https://github.com/astral-sh/ruff/pull/18127))
- `type[…]` is always assignable to `type` ([#18121](https://github.com/astral-sh/ruff/pull/18121))
- Support accessing `__builtins__` global ([#18118](https://github.com/astral-sh/ruff/pull/18118))
### Bug fixes
- Fix relative imports in stub packages ([#18132](https://github.com/astral-sh/ruff/pull/18132))
### Contributors
- [@MatthewMckee4](https://github.com/MatthewMckee4)
- [@felixscherz](https://github.com/felixscherz)
- [@BurntSushi](https://github.com/BurntSushi)
- [@maxmynter](https://github.com/maxmynter)
- [@sharkdp](https://github.com/sharkdp)
- [@TomerBin](https://github.com/TomerBin)
- [@MichaReiser](https://github.com/MichaReiser)
## 0.0.1-alpha.3
### Enhancements
- Include synthesized arguments in displayed counts for `too-many-positional-arguments` ([#18098](https://github.com/astral-sh/ruff/pull/18098))
### Bug fixes
- Fix `redundant-cast` false positives when casting to `Unknown` ([#18111](https://github.com/astral-sh/ruff/pull/18111))
- Fix normalization of unions containing instances parameterized with unions ([#18112](https://github.com/astral-sh/ruff/pull/18112))
- Make dataclass instances adhere to DataclassInstance ([#18115](https://github.com/astral-sh/ruff/pull/18115))
### CLI
- Change layout of extra verbose output and respect `--color` for verbose output ([#18089](https://github.com/astral-sh/ruff/pull/18089))
### Documentation
- Use Cargo-style versions in the changelog ([#397](https://github.com/astral-sh/ty/pull/397))
### Contributors
- [@zanieb](https://github.com/zanieb)
- [@sharkdp](https://github.com/sharkdp)
- [@AlexWaygood](https://github.com/AlexWaygood)
- [@InSyncWithFoo](https://github.com/InSyncWithFoo)
- [@MichaReiser](https://github.com/MichaReiser)
## 0.0.1-alpha.2
### Enhancements
- Improve diagnostics for failure to call overloaded function ([#18073](https://github.com/astral-sh/ruff/pull/18073))
- Fix inconsistent casing in `invalid-return-type` diagnostic ([#18084](https://github.com/astral-sh/ruff/pull/18084))
- Add type-expression syntax link to `invalid-type-expression` diagnostics ([#18104](https://github.com/astral-sh/ruff/pull/18104))
### Bug fixes
- Add cycle handling for unpacking targets ([#18078](https://github.com/astral-sh/ruff/pull/18078))
- Do not look up `__init__` on instances ([#18092](https://github.com/astral-sh/ruff/pull/18092))
### Typing
- Infer parameter specializations of explicitly implemented generic protocols ([#18054](https://github.com/astral-sh/ruff/pull/18054))
- Check assignments to implicit global symbols are assignable to the types declared on `types.ModuleType` ([#18077](https://github.com/astral-sh/ruff/pull/18077))
- Fix various generics-related TODOs ([#18062](https://github.com/astral-sh/ruff/pull/18062))
### Documentation
- Fix rule link in the configuration description ([#381](https://github.com/astral-sh/ty/pull/381))
- Use `https://ty.dev/rules` when linking to the rules table ([#18072](https://github.com/astral-sh/ruff/pull/18072))
- Use `ty server` instead of `ty lsp` ([#360](https://github.com/astral-sh/ty/pull/360))
- Fix missing `>` in HTML anchor tags in CLI reference ([#18096](https://github.com/astral-sh/ruff/pull/18096))
- Fix link to rules docs ([#378](https://github.com/astral-sh/ty/pull/378))
- Fix repository in README transform script ([#361](https://github.com/astral-sh/ty/pull/361))
### Contributors
- [@dhruvmanila](https://github.com/dhruvmanila)
- [@Usul-Dev](https://github.com/Usul-Dev)
- [@dcreager](https://github.com/dcreager)
- [@AlexWaygood](https://github.com/AlexWaygood)
- [@BurntSushi](https://github.com/BurntSushi)
- [@MichaReiser](https://github.com/MichaReiser)
- [@frgfm](https://github.com/frgfm)
- [@kiran-4444](https://github.com/kiran-4444)
- [@sharkdp](https://github.com/sharkdp)
- [@eruditmorina](https://github.com/eruditmorina)
## 0.0.1-alpha.1
### Enhancements
- Add basic support for non-virtual Python environments ([#17991](https://github.com/astral-sh/ruff/pull/17991))
- Do not allow invalid virtual environments from discovered `.venv` or `VIRTUAL_ENV` ([#18003](https://github.com/astral-sh/ruff/pull/18003))
- Refine message for why a rule is enabled ([#18038](https://github.com/astral-sh/ruff/pull/18038))
- Update `--python` to accept paths to executables in environments ([#17954](https://github.com/astral-sh/ruff/pull/17954))
- Improve diagnostics for `assert_type` and `assert_never` ([#18050](https://github.com/astral-sh/ruff/pull/18050))
- Add a note to the diagnostic if a new builtin is used on an old Python version ([#18068](https://github.com/astral-sh/ruff/pull/18068))
### Bug fixes
- Fix infinite recursion bug in `is_disjoint_from` ([#18043](https://github.com/astral-sh/ruff/pull/18043))
- Recognize submodules in self-referential imports ([#18005](https://github.com/astral-sh/ruff/pull/18005))
### Typing
- Allow a class to inherit from an intersection if the intersection contains a dynamic type and the intersection is not disjoint from `type` ([#18055](https://github.com/astral-sh/ruff/pull/18055))
- Allow classes to inherit from `type[Any]` or `type[Unknown]` ([#18060](https://github.com/astral-sh/ruff/pull/18060))
- Apply function specialization to all overloads ([#18020](https://github.com/astral-sh/ruff/pull/18020))
- Implement `DataClassInstance` protocol for dataclasses ([#18018](https://github.com/astral-sh/ruff/pull/18018))
- Induct into instances and subclasses when finding and applying generics ([#18052](https://github.com/astral-sh/ruff/pull/18052))
- Infer parameter specializations of generic aliases ([#18021](https://github.com/astral-sh/ruff/pull/18021))
- Narrowing for `hasattr()` ([#18053](https://github.com/astral-sh/ruff/pull/18053))
- Silence false positives for PEP-695 ParamSpec annotations ([#18001](https://github.com/astral-sh/ruff/pull/18001))
- Understand homogeneous tuple annotations ([#17998](https://github.com/astral-sh/ruff/pull/17998))
- `__file__` is always a string inside a Python module ([#18071](https://github.com/astral-sh/ruff/pull/18071))
### CLI
- Avoid initializing progress bars early ([#18049](https://github.com/astral-sh/ruff/pull/18049))
### Contributors
- [@soof-golan](https://github.com/soof-golan)
- [@ibraheemdev](https://github.com/ibraheemdev)
- [@dhruvmanila](https://github.com/dhruvmanila)
- [@charliermarsh](https://github.com/charliermarsh)
- [@MichaReiser](https://github.com/MichaReiser)
- [@carljm](https://github.com/carljm)
- [@abhijeetbodas2001](https://github.com/abhijeetbodas2001)
- [@zanieb](https://github.com/zanieb)
- [@AlexWaygood](https://github.com/AlexWaygood)
- [@dcreager](https://github.com/dcreager)
- [@mtshiba](https://github.com/mtshiba)
- [@sharkdp](https://github.com/sharkdp)
## 0.0.0-alpha.8
### Changes
- Add `--config` CLI arg ([#17697](https://github.com/astral-sh/ruff/pull/17697))
- Add CLI documentation and update README ([#284](https://github.com/astral-sh/ty/pull/284))
- Add a warning about pre-release status to the CLI ([#17983](https://github.com/astral-sh/ruff/pull/17983))
- Add missing bitwise-operator branches for boolean and integer arithmetic ([#17949](https://github.com/astral-sh/ruff/pull/17949))
- Add progress bar for `ty check` ([#17965](https://github.com/astral-sh/ruff/pull/17965))
- Add CLI reference ([#17978](https://github.com/astral-sh/ruff/pull/17978))
- Change default severity for `unbound-reference` to `error` ([#17936](https://github.com/astral-sh/ruff/pull/17936))
- Change range of `revealed-type` diagnostic to be the range of the argument passed in, not the whole call ([#17980](https://github.com/astral-sh/ruff/pull/17980))
- Default to latest supported Python version ([#17938](https://github.com/astral-sh/ruff/pull/17938))
- Display "All checks passed!" message in green ([#17982](https://github.com/astral-sh/ruff/pull/17982))
- Document configuration schema ([#17950](https://github.com/astral-sh/ruff/pull/17950))
- Generate and add rules table ([#17953](https://github.com/astral-sh/ruff/pull/17953))
- Handle type variables that have other type variables as a default ([#17956](https://github.com/astral-sh/ruff/pull/17956))
- Ignore `possibly-unresolved-reference` by default ([#17934](https://github.com/astral-sh/ruff/pull/17934))
- Implement `global` handling and `load-before-global-declaration` syntax error ([#17637](https://github.com/astral-sh/ruff/pull/17637))
- Make `unused-ignore-comment` disabled by default for now ([#17955](https://github.com/astral-sh/ruff/pull/17955))
- Recognise functions containing `yield from` expressions as being generator functions ([#17930](https://github.com/astral-sh/ruff/pull/17930))
- Fix stack overflow on recursive protocols ([#17929](https://github.com/astral-sh/ruff/pull/17929))
- Report duplicate `Protocol` or `Generic` base classes with `[duplicate-base]`, not `[inconsistent-mro]` ([#17971](https://github.com/astral-sh/ruff/pull/17971))
- Respect the gradual guarantee when reporting errors in resolving MROs ([#17962](https://github.com/astral-sh/ruff/pull/17962))
- Support `typing.Self` in methods ([#17689](https://github.com/astral-sh/ruff/pull/17689))
- Support extending `__all__` from an imported module even when the module is not an `ExprName` node ([#17947](https://github.com/astral-sh/ruff/pull/17947))
- Support extending `__all__` with a literal tuple or set as well as a literal list ([#17948](https://github.com/astral-sh/ruff/pull/17948))
- Understand classes that inherit from subscripted `Protocol[]` as generic ([#17832](https://github.com/astral-sh/ruff/pull/17832))
- Update ty metadata ([#17943](https://github.com/astral-sh/ruff/pull/17943))
- Add `py.typed` ([#276](https://github.com/astral-sh/ty/pull/276))
- Bottom-up improvement of diagnostic messages for union type function calls ([#17984](https://github.com/astral-sh/ruff/pull/17984))
- Fix more ecosystem/fuzzer panics with fixpoint ([#17758](https://github.com/astral-sh/ruff/pull/17758))
- Remove `lint:` prefix from top-level diagnostic preamble ([#17987](https://github.com/astral-sh/ruff/pull/17987))
### Contributors
- [@Glyphack](https://github.com/Glyphack)
- [@BurntSushi](https://github.com/BurntSushi)
- [@paul-nameless](https://github.com/paul-nameless)
- [@MichaReiser](https://github.com/MichaReiser)
- [@ntbre](https://github.com/ntBre)
- [@ibraheemdev](https://github.com/ibraheemdev)
- [@sharkdp](https://github.com/sharkdp)
- [@thejchap](https://github.com/thejchap)
- [@carljm](https://github.com/carljm)
- [@jorenham](https://github.com/jorenham)
- [@AlexWaygood](https://github.com/AlexWaygood)
- [@dcreager](https://github.com/dcreager)
## /CODE_OF_CONDUCT.md
# Contributor Covenant Code of Conduct
- [Our Pledge](#our-pledge)
- [Our Standards](#our-standards)
- [Enforcement Responsibilities](#enforcement-responsibilities)
- [Scope](#scope)
- [Enforcement](#enforcement)
- [Enforcement Guidelines](#enforcement-guidelines)
- [1. Correction](#1-correction)
- [2. Warning](#2-warning)
- [3. Temporary Ban](#3-temporary-ban)
- [4. Permanent Ban](#4-permanent-ban)
- [Attribution](#attribution)
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
- Demonstrating empathy and kindness toward other people
- Being respectful of differing opinions, viewpoints, and experiences
- Giving and gracefully accepting constructive feedback
- Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
- Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
- The use of sexualized language or imagery, and sexual attention or
advances of any kind
- Trolling, insulting or derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or email
address, without their explicit permission
- Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
<hey@astral.sh>.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available [here](https://www.contributor-covenant.org/version/2/0/code_of_conduct.html).
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
For answers to common questions about this code of conduct, see the [FAQ](https://www.contributor-covenant.org/faq).
Translations are available [here](https://www.contributor-covenant.org/translations).
[homepage]: https://www.contributor-covenant.org
## /CONTRIBUTING.md
# Contributing
> [!IMPORTANT]
> If you want to contribute changes to ty's core, please check out the
> [dedicated `ty` contributing guide](https://github.com/astral-sh/ruff/blob/main/crates/ty/CONTRIBUTING.md).
> Keep reading if you want to contribute to ty's documentation or release process instead.
## Repository structure
This repository contains ty's documentation and release infrastructure. The core of ty's Rust codebase is
located in the [Ruff](https://github.com/astral-sh/ruff) repository. While the relationship between these
two projects will evolve over time, they currently share foundational crates and it's easiest to use a single
repository for the Rust development.
ty's command-line help text, and part of `docs/reference/`, are auto-generated from Rust code in the Ruff
repository, using generation scripts that live in
[`crates/ruff_dev/src/`](https://github.com/astral-sh/ruff/blob/main/crates/ruff_dev/src/):
- [Configuration options](https://docs.astral.sh/ty/reference/configuration/), from
[ruff/crates/ty_project/src/metadata/options.rs](https://github.com/astral-sh/ruff/blob/main/crates/ty_project/src/metadata/options.rs)
- [Rules](https://docs.astral.sh/ty/reference/rules/), from
[ruff/crates/ty_python_semantic/src/](https://github.com/astral-sh/ruff/blob/main/crates/ty_python_semantic/src/)
- [Command-line interface reference](https://docs.astral.sh/ty/reference/cli/), from
[ruff/crates/ty/src/args.rs](https://github.com/astral-sh/ruff/blob/main/crates/ty/src/args.rs)
The Ruff repository is included as a submodule inside this repository to allow ty's release tags to reflect
an exact snapshot of the Ruff project. The submodule is only updated on release. To see the latest development
code, check out the `main` branch of the Ruff repository.
## Getting started with the ty repository
Clone the repository:
```shell
git clone https://github.com/astral-sh/ty.git
```
Then, ensure the submodule is initialized:
```shell
git submodule update --init --recursive
```
### Prerequisites
You'll need [uv](https://docs.astral.sh/uv/getting-started/installation/) (or `pipx` and `pip`) to
run Python utility commands.
You can optionally install pre-commit hooks to automatically run the validation checks
when making a commit:
```shell
uv tool install pre-commit
pre-commit install
```
## Building the Python package
The Python package can be built with any Python build frontend (Maturin is used as a backend), e.g.:
```shell
uv build
```
## Updating the Ruff commit
To update the Ruff submodule to the latest commit:
```shell
git -C ruff pull origin main
```
Or, to update the Ruff submodule to a specific commit:
```shell
git -C ruff checkout <commit>
```
To commit the changes:
```shell
commit=$(git -C ruff rev-parse --short HEAD)
git switch -c "sync/ruff-${commit}"
git add ruff
git commit -m "Update ruff submodule to https://github.com/astral-sh/ruff/commit/${commit}"
```
To restore the Ruff submodule to a clean-state, reset, then update the submodule:
```shell
git -C ruff reset --hard
git submodule update
```
To restore the Ruff submodule to the commit from `main`:
```shell
git -C ruff reset --hard $(git ls-tree main -- ruff | awk '{print $3}')
git add ruff
```
## Documentation
To preview any changes to the documentation locally run the development server with:
```shell
# For contributors.
uvx --with-requirements docs/requirements.txt -- mkdocs serve -f mkdocs.public.yml
# For members of the Astral org, which has access to MkDocs Insiders via sponsorship.
uvx --with-requirements docs/requirements-insiders.txt -- mkdocs serve -f mkdocs.insiders.yml
```
The documentation should then be available locally at
[http://127.0.0.1:8000/ty/](http://127.0.0.1:8000/ty/).
To update the documentation dependencies, edit `docs/requirements.in` and
`docs/requirements-insiders.in`, then run:
```shell
uv pip compile docs/requirements.in -o docs/requirements.txt --universal -p 3.12
uv pip compile docs/requirements-insiders.in -o docs/requirements-insiders.txt --universal -p 3.12
```
Documentation is deployed automatically on release by publishing to the
[Astral documentation](https://github.com/astral-sh/docs) repository, which itself deploys via
Cloudflare Pages.
After making changes to the documentation, format the markdown files with:
```shell
npx prettier --prose-wrap always --write "**/*.md"
```
## Releasing ty
Releases can only be performed by Astral team members.
Preparation for the release is automated.
1. Checkout the `main` branch and run `git pull origin main --recurse-submodules --tags`.
1. Create and checkout a new branch for the release.
1. Run `./scripts/release.sh`.
The release script will:
- Update the Ruff submodule to the latest commit on `main` upstream
- Generate changelog entries based on pull requests here, and in Ruff
- Bump the versions in the `pyproject.toml` and `dist-workspace.toml`
- Update the generated reference documentation in `docs/reference`
1. Editorialize the `CHANGELOG.md` file to ensure entries are consistently styled.
This usually involves simple edits, like consistent capitalization and leading verbs like
"Add ...".
1. Create a pull request with the changelog and version changes
The pull requests are usually titled as: `Bump version to <version>`.
Binary builds will automatically be tested for the release.
1. Merge the pull request.
1. Run the [release workflow](https://github.com/astral-sh/ty/actions/workflows/release.yml) with
the version tag.
**Do not include a leading `v`**.
When running the release workflow for pre-release versions, use the Cargo version format (not PEP
440), e.g. `0.0.1-alpha.5` (not `0.0.1a5`). For stable releases, these formats are identical.
The release will automatically be created on GitHub after the distributions are published.
1. Run `uv run --no-project ./scripts/update_schemastore.py`
This script will prepare a branch to update the `ty.json` schema in the `schemastore`
repository.
Follow the link in the script's output to submit the pull request.
The script is a no-op if there are no schema changes.
1. If necessary, update and release [`ty-vscode`](https://github.com/astral-sh/ty-vscode).
The instructions are in the `ty-vscode` repository.
Updating the extension bumps the bundled ty version, which is used if ty is not installed.
Updating the extension is required for:
- Minor releases
- Patch releases, if a critical bug in `ty server` is fixed
- When releasing new `ty server` features that require changes in `ty-vscode`
## /Dockerfile
``` path="/Dockerfile"
FROM --platform=$BUILDPLATFORM ubuntu AS build
ENV HOME="/root"
WORKDIR $HOME
RUN apt update && apt install -y build-essential curl python3-venv
# Setup zig as cross compiling linker
RUN python3 -m venv $HOME/.venv
RUN .venv/bin/pip install cargo-zigbuild
ENV PATH="$HOME/.venv/bin:$PATH"
# Change to the ruff directory, which is the root for our build
WORKDIR $HOME/ruff
# Install rust
ARG TARGETPLATFORM
RUN case "$TARGETPLATFORM" in \
"linux/arm64") echo "aarch64-unknown-linux-musl" > rust_target.txt ;; \
"linux/amd64") echo "x86_64-unknown-linux-musl" > rust_target.txt ;; \
*) exit 1 ;; \
esac
# Update rustup whenever we bump the rust version
COPY ruff/rust-toolchain.toml rust-toolchain.toml
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --target $(cat rust_target.txt) --profile minimal --default-toolchain none
ENV PATH="$HOME/.cargo/bin:$PATH"
# Installs the correct toolchain version from rust-toolchain.toml and then the musl target
RUN rustup target add $(cat rust_target.txt)
# Build
COPY ruff/crates crates
COPY ruff/Cargo.toml Cargo.toml
COPY ruff/Cargo.lock Cargo.lock
RUN cargo zigbuild --bin ty --target $(cat rust_target.txt) --release
RUN cp target/$(cat rust_target.txt)/release/ty /ty
# TODO: Optimize binary size, with a version that also works when cross compiling
# RUN strip --strip-all /ty
FROM scratch
COPY --from=build /ty /ty
WORKDIR /io
ENTRYPOINT ["/ty"]
```
## /README.md
# ty
[](https://github.com/astral-sh/ty)
[](https://pypi.python.org/pypi/ty)
[](https://discord.com/invite/astral-sh)
An extremely fast Python type checker and language server, written in Rust.
> [!WARNING]
>
> ty is in preview and is not ready for production use.
>
> We're working hard to make ty stable and feature-complete, but until then, expect to encounter bugs,
> missing features, and fatal errors.
## Getting started
Try out the [online playground](https://play.ty.dev), or run ty with
[uvx](https://docs.astral.sh/uv/guides/tools/#running-tools) to get started quickly:
```shell
uvx ty
```
For other ways to install ty, see the [installation](https://docs.astral.sh/ty/installation/) documentation.
If you do not provide a subcommand, ty will list available commands — for detailed information about
command-line options, see the [CLI reference](https://docs.astral.sh/ty/reference/cli/).
Use the `check` command to run the type checker:
```shell
uvx ty check
```
ty will run on all Python files in the working directory and or subdirectories. If used from a
project, ty will run on all Python files in the project (starting in the directory with the
`pyproject.toml`)
You can also provide specific paths to check:
```shell
uvx ty check example.py
```
When type checking, ty will find installed packages in the active virtual environment (via
`VIRTUAL_ENV`) or discover a virtual environment named `.venv` in the project root or working
directory. It will not find packages in non-virtual environments without specifying the target path
with `--python`. See the [module discovery](https://docs.astral.sh/ty/modules/) documentation for
details.
## Learning more
To learn more about using ty, see the [documentation](https://docs.astral.sh/ty/).
## Getting involved
If you have questions or want to report a bug, please open an
[issue](https://github.com/astral-sh/ty/issues) in this repository.
Development of this project takes place in the [Ruff](https://github.com/astral-sh/ruff) repository
at this time. Please [open pull requests](https://github.com/astral-sh/ruff/pulls) there for changes
to anything in the `ruff` submodule (which includes all of the Rust source code).
See the
[contributing guide](./CONTRIBUTING.md) for more details.
## License
ty is licensed under the MIT license ([LICENSE](LICENSE) or
<https://opensource.org/licenses/MIT>).
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in ty
by you, as defined in the MIT license, shall be licensed as above, without any additional terms or
conditions.
<div align="center">
<a target="_blank" href="https://astral.sh" style="background:none">
<img src="https://raw.githubusercontent.com/astral-sh/uv/main/assets/svg/Astral.svg" alt="Made by Astral">
</a>
</div>
## /SECURITY.md
# Security policy
## Reporting a vulnerability
If you have found a possible vulnerability, please email `security at astral dot sh`.
## Bug bounties
While we sincerely appreciate and encourage reports of suspected security problems, please note that
Astral does not currently run any bug bounty programs.
## Vulnerability disclosures
Critical vulnerabilities will be disclosed via GitHub's
[security advisory](https://github.com/astral-sh/ty/security) system.
## /_typos.toml
```toml path="/_typos.toml"
[files]
extend-exclude = []
[default.extend-words]
[default]
extend-ignore-re = [
# Line ignore with trailing "spellchecker:disable-line"
"(?Rm)^.*#\\s*spellchecker:disable-line{{contextString}}quot;,
"LICENSEs",
"ntBre"
]
```
## /assets/badge/v0.json
```json path="/assets/badge/v0.json"
{
"label": "",
"message": "ty",
"logoSvg": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"48\" height=\"48\"><path d=\"M48 7.7H27.8V0h-24v7.7H0v18.2h3.8v14.3c0 4.3 3.5 7.8 7.8 7.8H48V29.8H27.8v-3.9h12.4c4.3 0 7.8-3.5 7.8-7.8V7.7Z\" fill=\"#46ebe1\"/></svg>",
"logoWidth": 10,
"labelColor": "grey",
"color": "#261230"
}
```
## /dist-workspace.toml
```toml path="/dist-workspace.toml"
[workspace]
members = ["cargo:./ruff"]
packages = ["ty"]
version = "0.0.1-alpha.25"
# Config for 'dist'
[dist]
# The preferred dist version to use in CI (Cargo.toml SemVer syntax)
cargo-dist-version = "0.30.0"
# Whether to consider the binaries in a package for distribution (defaults true)
dist = false
# CI backends to support
ci = "github"
# The installers to generate for each app
installers = ["shell", "powershell"]
# The archive format to use for windows builds (defaults .zip)
windows-archive = ".zip"
# The archive format to use for non-windows builds (defaults .tar.xz)
unix-archive = ".tar.gz"
# Target platforms to build apps for (Rust target-triple syntax)
targets = [
"aarch64-apple-darwin",
"aarch64-unknown-linux-gnu",
"aarch64-unknown-linux-musl",
"aarch64-pc-windows-msvc",
"arm-unknown-linux-musleabihf",
"armv7-unknown-linux-gnueabihf",
"armv7-unknown-linux-musleabihf",
"x86_64-apple-darwin",
"powerpc64-unknown-linux-gnu",
"powerpc64le-unknown-linux-gnu",
"s390x-unknown-linux-gnu",
"x86_64-unknown-linux-gnu",
"x86_64-unknown-linux-musl",
"x86_64-pc-windows-msvc",
"i686-unknown-linux-gnu",
"i686-unknown-linux-musl",
"i686-pc-windows-msvc",
]
# Whether to auto-include files like READMEs, LICENSEs, and CHANGELOGs (default true)
auto-includes = false
# Whether dist should create a Github Release or use an existing draft
create-release = true
# Which actions to run on pull requests
pr-run-mode = "plan"
# Whether to publish prereleases to package managers
publish-prereleases = true
# Whether CI should trigger releases with dispatches instead of tag pushes
dispatch-releases = true
# Which phase dist should use to create the GitHub release
github-release = "announce"
# Whether CI should include auto-generated code to build local artifacts
build-local-artifacts = false
# Local artifacts jobs to run in CI
local-artifacts-jobs = ["./build-binaries", "./build-docker"]
# Publish jobs to run in CI
publish-jobs = ["./publish-pypi"]
# Post-announce jobs to run in CI
post-announce-jobs = ["./publish-docs"]
# Custom permissions for GitHub Jobs
github-custom-job-permissions = { "build-docker" = { packages = "write", contents = "read" } }
# Whether to install an updater program
install-updater = false
# Path that installers should place binaries in
install-path = ["$XDG_BIN_HOME/", "$XDG_DATA_HOME/../bin", "~/.local/bin"]
# Whether source tarballs should include submodules
recursive-tarball = true
[dist.github-custom-runners]
global = "depot-ubuntu-latest-4"
[dist.github-action-commits]
"actions/checkout" = "ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493" # v5.0.0
"actions/upload-artifact" = "330a01c490aca151604b8cf639adc76d48f6c5d4" # v5.0.0
"actions/download-artifact" = "018cc2cf5baa6db3ef3c5f8a56943fffe632ef53" # v6.0.0
"actions/attest-build-provenance" = "c074443f1aee8d4aeeae555aebba3282517141b2" #v2.2.3
```
## /docs/.overrides/main.html
```html path="/docs/.overrides/main.html"
{% extends "base.html" %}
{% block htmltitle %}
{% if page.meta and page.meta.title %}
<title>{{ page.meta.title }} | {{ config.site_name }}</title>
{% elif page.title and not page.is_homepage %}
<title>{{ page.title | striptags }} | {{ config.site_name }}</title>
{% else %}
<title>{{ config.site_name }}</title>
{% endif %}
{% endblock %}
{% block extrahead %}
<link rel="apple-touch-icon" sizes="180x180" href="https://docs.astral.sh/static/apple-touch-icon.png"/>
<link rel="icon" type="image/png" sizes="32x32" href="https://docs.astral.sh/static/favicon-32x32.png"/>
<link rel="icon" type="image/png" sizes="16x16" href="https://docs.astral.sh/static/favicon-16x16.png"/>
<link rel="manifest" href="https://docs.astral.sh/static/site.webmanifest"/>
<link rel="mask-icon" href="https://docs.astral.sh/static/safari-pinned-tab.svg" color="#2e183d"/>
<meta name="msapplication-TileColor" content="#d7ff64"/>
<meta name="theme-color" content="#ffffff"/>
<meta name="robots" content="index,follow"/>
<script type="application/ld+json">
{
{% if page and page.meta.git_revision_date_localized_raw_iso_datetime %}
"datePublished": "{{ page.meta.git_revision_date_localized_raw_iso_datetime }}Z",
"dateModified": "{{ page.meta.git_revision_date_localized_raw_iso_datetime }}Z",
{% endif %}
"@context": "https://schema.org",
"@type": "WebSite",
"name": "Astral Docs",
"url": "https://docs.astral.sh"
}
</script>
{% endblock %}
```
## /docs/.overrides/partials/integrations/analytics/fathom.html
```html path="/docs/.overrides/partials/integrations/analytics/fathom.html"
<script src="https://cdn.usefathom.com/script.js" data-site="ESKBRHGN" defer></script>
```
## /docs/assets/favicon.ico
Binary file available at https://raw.githubusercontent.com/astral-sh/ty/refs/heads/main/docs/assets/favicon.ico
## /docs/assets/logo-letter.svg
```svg path="/docs/assets/logo-letter.svg"
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M48 7.68H27.84V0H3.84V7.68H0V25.92H3.84V40.2136C3.84 44.5139 7.32607 48 11.6264 48H48V29.76H27.84V25.92H40.2136C44.5139 25.92 48 22.4339 48 18.1336V7.68Z" fill="#46EBE1"/>
</svg>
```
## /docs/configuration.md
# Configuration
## Configuration files
ty supports persistent configuration files at both the project- and user-level.
Specifically, ty will search for a `pyproject.toml` or `ty.toml` file in the current directory, or in the nearest parent directory.
If a `pyproject.toml` file is found, ty will read configuration from the `[tool.ty]` table. For example, to ignore the `index-out-of-bounds` rule, add the following to a `pyproject.toml`:
**`pyproject.toml`**:
```toml
[tool.ty.rules]
index-out-of-bounds = "ignore"
```
(If there is no `tool.ty` table, the `pyproject.toml` file will be ignored, and ty will continue searching in the directory hierarchy.)
ty will also search for `ty.toml` files, which follow an identical structure, but omit the `[tool.ty]` prefix. For example:
**`ty.toml`**:
```toml
[rules]
index-out-of-bounds = "ignore"
```
!!! note
`ty.toml` files take precedence over `pyproject.toml` files, so if both `ty.toml` and `pyproject.toml` files are present in a directory, configuration will be read from `ty.toml`, and the `[tool.ty]` section in the accompanying `pyproject.toml` will be ignored.
ty will also discover user-level configuration at `~/.config/ty/ty.toml` (or `$XDG_CONFIG_HOME/ty/ty.toml`) on macOS and Linux, or `%APPDATA%\ty\ty.toml` on Windows. User-level configuration must use the `ty.toml` format, rather than the `pyproject.toml` format, as a `pyproject.toml` is intended to define a Python project.
If project- and user-level configuration files are found, the settings will be merged, with project-level configuration taking precedence over the user-level configuration.
For example, if a string, number, or boolean is present in both the project- and user-level configuration tables, the project-level value will be used, and the user-level value will be ignored. If an array is present in both tables, the arrays will be merged, with the project-level settings appearing later in the merged array.
Settings provided via command line take precedence over persistent configuration.
See the [configuration](./reference/configuration.md) reference for an enumeration of the available settings.
## /docs/editors.md
# Editor integration
ty can be integrated with various editors to provide a seamless development experience.
## VS Code
The Astral team maintains an official VS Code extension.
Install the [ty extension](https://marketplace.visualstudio.com/items?itemName=astral-sh.ty) from the VS Code Marketplace.
See the extension's [README](https://github.com/astral-sh/ty-vscode) for more details on usage.
## Neovim
For Neovim 0.10 or earlier (with [`nvim-lspconfig`](https://github.com/neovim/nvim-lspconfig)):
```lua
require('lspconfig').ty.setup({
settings = {
ty = {
-- ty language server settings go here
}
}
})
```
For Neovim 0.11+ (with [`vim.lsp.config`](<https://neovim.io/doc/user/lsp.html#vim.lsp.config()>)):
```lua
-- Optional: Only required if you need to update the language server settings
vim.lsp.config('ty', {
settings = {
ty = {
-- ty language server settings go here
}
}
})
-- Required: Enable the language server
vim.lsp.enable('ty')
```
## Zed
ty is included with Zed out of the box (no extension required), although the default primary LSP for Python is basedpyright.
You can enable ty and disable basedpyright by adding this to your `settings.json` file:
```json
{
"languages": {
"Python": {
"language_servers": [
// Disable basedpyright and enable Ty, and otherwise
// use the default configuration.
"ty",
"!basedpyright",
"..."
]
}
}
}
```
More information in [Zed's documentation](https://zed.dev/docs/languages/python#configure-python-language-servers-in-zed).
## Other editors
ty can be used with any editor that supports the [language server
protocol](https://microsoft.github.io/language-server-protocol/).
To start the language server, use the `server` subcommand:
```shell
ty server
```
Refer to your editor's documentation to learn how to connect to an LSP server.
See the [editor settings](./reference/editor-settings.md) for more details on configuring the language
server.
## /docs/exclusions.md
# Excluding files
ty automatically discovers all Python files in your project. You can customize where ty searches by using the [`src.include`](./reference/configuration.md#include) and [`src.exclude`](./reference/configuration.md#exclude) settings.
For example, with the following configuration, ty checks all Python files in the `src` and `tests` directories except those in the `src/generated` directory:
```toml
[tool.ty.src]
include = ["src", "tests"]
exclude = ["src/generated"]
```
By default, ty excludes a [variety of commonly ignored directories](./reference/configuration.md#exclude). If you want to include one of these directories, you can do so by adding a negative `exclude`:
```toml
[tool.ty.src]
# Remove `build` from the excluded directories.
exclude = ["!**/build/"]
```
By default, ty ignores files listed in an `.ignore` or `.gitignore` file. To disable this functionality, set [`respect-ignore-files`](./reference/configuration.md#respect-ignore-files) to `false`.
You may also explicitly pass the paths that ty should check, e.g.:
```shell
ty check src scripts/benchmark.py
```
Paths that are passed as positional arguments to `ty check` are included even if they would otherwise be ignored through `exclude` filters or an ignore-file.
## Include and exclude syntax
Both `include` and `exclude` support gitignore like glob patterns:
- `src/` matches a directory (including its contents) named `src`.
- `src` matches a file or directory (including its contents) named `src`.
- `*` matches any (possibly empty) sequence of characters (except `/`).
- `**` matches zero or more path components.
This sequence **must** form a single path component, so both `./**a` and `./b**/` are invalid and will result in an error.
A sequence of more than two consecutive `*` characters is also invalid.
- `?` matches any single character except `/`
- `[abc]` matches any character inside the brackets. Character sequences can also specify ranges of characters, as ordered by Unicode,
so e.g. `[0-9]` specifies any character between `0` and `9` inclusive. An unclosed bracket is invalid.
All patterns are anchored: The pattern `src` only includes `<project_root>/src` but not something like `<project_root>/test/src`. To include any directory named `src`, use the prefix match `**/src`. The same applies for exclude patterns where `src` only excludes `<project_root>/src` but not something like `<project_root>/test/src`.
!!! note
A prefix include pattern like `**/src` can notably slow down the Python file discovery.
All fields accepting patterns use the reduced portable glob syntax from [PEP 639](https://peps.python.org/pep-0639/#add-license-FILES-key), with the addition that characters can be escaped with a backslash.
## /docs/index.md
# ty
An extremely fast Python type checker, written in Rust.
<!-- TODO
## Highlights
- ...
-->
## Getting started
Try out the [online playground](https://play.ty.dev), or run ty with
[uvx](https://docs.astral.sh/uv/guides/tools/#running-tools) to get started quickly:
```shell
uvx ty
```
For other ways to install ty, see the [installation](./installation.md) documentation.
If you do not provide a subcommand, ty will list available commands — for detailed information about
command-line options, see the [CLI reference](./reference/cli.md).
Use the `check` command to run the type checker:
```shell
uvx ty check
```
ty will run on all Python files in the working directory and or subdirectories. If used from a
project, ty will run on all Python files in the project (starting in the directory with the
`pyproject.toml`)
You can also provide specific paths to check:
```shell
uvx ty check example.py
```
When type checking, ty will find installed packages in the active virtual environment (via
`VIRTUAL_ENV`) or discover a virtual environment named `.venv` in the project root or working
directory. It will not find packages in non-virtual environments without specifying the target path
with `--python`. See the [module discovery](./modules.md) documentation for
details.
### Usage
Run [`ty check`](./reference/cli.md#ty-check), in your project's top-level directory,
to check the project for type errors using ty's default configuration.
If this provokes a cascade of errors, and you are using the standard library `venv` module
to provide your virtual environment, add the venv directory to your `.gitignore`
or `.ignore` file and then retry.
## /docs/installation.md
# Installing ty
## Adding ty to your project
Use [uv](https://github.com/astral-sh/uv) (or your project manager of choice) to add ty as a
development dependency:
```shell
uv add --dev ty
```
Adding ty as a dependency ensures that all developers on the project are using the same version of
ty.
Then, use `uv run` to invoke ty:
```shell
uv run ty
```
## Installing globally
Install ty globally with uv:
```shell
uv tool install ty@latest
```
Or, pipx:
```shell
pipx install ty
```
## Installing with pip
Install ty into your current Python environment with pip:
```shell
pip install ty
```
## /docs/js/extra.js
```js path="/docs/js/extra.js"
function cleanupClipboardText(targetSelector) {
const targetElement = document.querySelector(targetSelector);
// exclude "Generic Prompt" and "Generic Output" spans from copy
const excludedClasses = ["gp", "go"];
const clipboardText = Array.from(targetElement.childNodes)
.filter(
(node) =>
!excludedClasses.some((className) =>
node?.classList?.contains(className)
)
)
.map((node) => node.textContent)
.filter((s) => s != "");
return clipboardText.join("").trim();
}
// Sets copy text to attributes lazily using an Intersection Observer.
function setCopyText() {
// The `data-clipboard-text` attribute allows for customized content in the copy
// See: https://www.npmjs.com/package/clipboard#copy-text-from-attribute
const attr = "clipboardText";
// all "copy" buttons whose target selector is a <code> element
const elements = document.querySelectorAll(
'button[data-clipboard-target$="code"]'
);
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
// target in the viewport that have not been patched
if (
entry.intersectionRatio > 0 &&
entry.target.dataset[attr] === undefined
) {
entry.target.dataset[attr] = cleanupClipboardText(
entry.target.dataset.clipboardTarget
);
}
});
});
elements.forEach((elt) => {
observer.observe(elt);
});
}
// Using the document$ observable is particularly important if you are using instant loading since
// it will not result in a page refresh in the browser
// See `How to integrate with third-party JavaScript libraries` guideline:
// https://squidfunk.github.io/mkdocs-material/customization/?h=javascript#additional-javascript
document$.subscribe(function () {
setCopyText();
});
// Use client-side redirects for anchors that have moved.
// Other redirects should use `redirect_maps` in the `mkdocs.yml` file instead.
(function () {
// (there are no redirects yet)
let redirect_maps = {};
// The prefix for the site, see `site_dir` in `mkdocs.yml`
let site_dir = "ty";
function get_path() {
var path = window.location.pathname;
// Trim the site prefix
if (path.startsWith("/" + site_dir + "/")) {
path = path.slice(site_dir.length + 2);
}
// Always include a trailing `/`
if (!path.endsWith("/")) {
path = path + "/";
}
// Check for an anchor
var anchor = window.location.hash.substring(1);
if (!anchor) {
return path;
}
return path + "#" + anchor;
}
let path = get_path();
if (path && redirect_maps.hasOwnProperty(path)) {
window.location.replace("/" + site_dir + "/" + redirect_maps[path]);
}
})();
```
## /docs/modules.md
# Module discovery
## First-party modules
First-party modules are Python files that are part of your project source code.
By default, ty searches for first-party modules in the project's root directory or the `src`
directory, if present.
If your project uses a different layout, configure the project's
[`environment.root`](./reference/configuration.md#root) in your `pyproject.toml` or `ty.toml`. For example,
if your project's code is in an `app/` directory:
```text
example-pkg
├── README.md
├── pyproject.toml
└── app
└── example_pkg
└── __init__.py
```
then set [`environment.root`](./reference/configuration.md#root) in your `pyproject.toml` to `["./app"]`:
```toml
[tool.ty.environment]
root = ["./app"]
```
Note that `python` and `tests` folders are automatically added to the project `root` if they exist,
and if they are not packages themselves (i.e. they do not contain an `__init__.py` file or an
`__init__.pyi` file).
## Third-party modules
Third-party modules are Python packages that are not part of your project or the standard library.
These are usually declared as dependencies in a `pyproject.toml` or `requirements.txt` file
and installed using a package manager like uv or pip. Examples of popular third-party
modules are `requests`, `numpy` and `django`.
ty searches for third-party modules in the configured [Python environment](#python-environment).
## Python environment
The Python environment is used for discovery of third-party modules.
By default, ty will attempt to discover a virtual environment.
First, ty checks for an active virtual environment using the `VIRTUAL_ENV` environment variable. If
not set, ty will search for a `.venv` directory in the project root or working directory. ty only
supports discovery of virtual environments at this time.
!!! note
When using project management tools, such as uv or Poetry, the `run` command usually automatically
activates the virtual environment and will be detected by ty.
The Python environment may be explicitly configured using the
[`environment.python`](./reference/configuration.md#python) setting or
[`--python`](./reference/cli.md#ty-check--python) flag.
When setting the environment explicitly, non-virtual environments can be provided.
## /docs/python-version.md
# Python version
The Python version affects allowed syntax, type definitions of the standard library, and type
definitions of first- and third-party modules that are conditional on the Python version.
For example, Python 3.10 introduced support for `match` statements and added the
`sys.stdlib_module_names` symbol to the standard library. Syntactic features always
need to be available in the lowest supported Python version, but symbols may be used
in a `sys.version_info` conditional branch:
```python
import sys
# `invalid-syntax` error if `python-version` is set to 3.9 or lower:
match "echo hello".split():
case ["echo", message]:
print(message)
case _:
print("unknown command")
# `unresolved-attribute` error if `python-version` is set to 3.9 or lower:
print(sys.stdlib_module_names)
if sys.version_info >= (3, 10):
# ok, because the usage is guarded by a version check:
print(sys.stdlib_module_names)
```
By default, the lower bound of the project's [`requires-python`](https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#python-requires) field (from the `pyproject.toml`) is
used as the target Python version, ensuring that features and symbols only available in newer Python
versions are not used.
If the `requires-python` field is not available but a virtual environment *has* been
configured or detected, ty will try to infer the Python version being used from the virtual
environment's metadata.
If no virtual environment is present or inferring the Python version from the metadata fails,
ty will fall back to the latest stable Python version supported by ty (currently 3.13).
The Python version may also be explicitly specified using the
[`python-version`](./reference/configuration.md#python-version) setting or the
[`--python-version`](./reference/cli.md#ty-check--python-version) flag.
## /docs/reference/cli.md
<!-- WARNING: This file is auto-generated (cargo dev generate-all). Edit the doc comments in 'crates/ty/src/args.rs' if you want to change anything here. -->
# CLI Reference
## ty
An extremely fast Python type checker.
<h3 class="cli-reference">Usage</h3>
```
ty <COMMAND>
```
<h3 class="cli-reference">Commands</h3>
<dl class="cli-reference"><dt><a href="#ty-check"><code>ty check</code></a></dt><dd><p>Check a project for type errors</p></dd>
<dt><a href="#ty-server"><code>ty server</code></a></dt><dd><p>Start the language server</p></dd>
<dt><a href="#ty-version"><code>ty version</code></a></dt><dd><p>Display ty's version</p></dd>
<dt><a href="#ty-help"><code>ty help</code></a></dt><dd><p>Print this message or the help of the given subcommand(s)</p></dd>
</dl>
## ty check
Check a project for type errors
<h3 class="cli-reference">Usage</h3>
```
ty check [OPTIONS] [PATH]...
```
<h3 class="cli-reference">Arguments</h3>
<dl class="cli-reference"><dt id="ty-check--paths"><a href="#ty-check--paths"><code>PATHS</code></a></dt><dd><p>List of files or directories to check [default: the project root]</p>
</dd></dl>
<h3 class="cli-reference">Options</h3>
<dl class="cli-reference"><dt id="ty-check--color"><a href="#ty-check--color"><code>--color</code></a> <i>when</i></dt><dd><p>Control when colored output is used</p>
<p>Possible values:</p>
<ul>
<li><code>auto</code>: Display colors if the output goes to an interactive terminal</li>
<li><code>always</code>: Always display colors</li>
<li><code>never</code>: Never display colors</li>
</ul></dd><dt id="ty-check--config"><a href="#ty-check--config"><code>--config</code></a>, <code>-c</code> <i>config-option</i></dt><dd><p>A TOML <code><KEY> = <VALUE></code> pair (such as you might find in a <code>ty.toml</code> configuration file)
overriding a specific configuration option.</p>
<p>Overrides of individual settings using this option always take precedence
over all configuration files.</p>
</dd><dt id="ty-check--config-file"><a href="#ty-check--config-file"><code>--config-file</code></a> <i>path</i></dt><dd><p>The path to a <code>ty.toml</code> file to use for configuration.</p>
<p>While ty configuration can be included in a <code>pyproject.toml</code> file, it is not allowed in this context.</p>
<p>May also be set with the <code>TY_CONFIG_FILE</code> environment variable.</p></dd><dt id="ty-check--error"><a href="#ty-check--error"><code>--error</code></a> <i>rule</i></dt><dd><p>Treat the given rule as having severity 'error'. Can be specified multiple times.</p>
</dd><dt id="ty-check--error-on-warning"><a href="#ty-check--error-on-warning"><code>--error-on-warning</code></a></dt><dd><p>Use exit code 1 if there are any warning-level diagnostics</p>
</dd><dt id="ty-check--exclude"><a href="#ty-check--exclude"><code>--exclude</code></a> <i>exclude</i></dt><dd><p>Glob patterns for files to exclude from type checking.</p>
<p>Uses gitignore-style syntax to exclude files and directories from type checking. Supports patterns like <code>tests/</code>, <code>*.tmp</code>, <code>**/__pycache__/**</code>.</p>
</dd><dt id="ty-check--exit-zero"><a href="#ty-check--exit-zero"><code>--exit-zero</code></a></dt><dd><p>Always use exit code 0, even when there are error-level diagnostics</p>
</dd><dt id="ty-check--extra-search-path"><a href="#ty-check--extra-search-path"><code>--extra-search-path</code></a> <i>path</i></dt><dd><p>Additional path to use as a module-resolution source (can be passed multiple times).</p>
<p>This is an advanced option that should usually only be used for first-party or third-party modules that are not installed into your Python environment in a conventional way. Use <code>--python</code> to point ty to your Python environment if it is in an unusual location.</p>
</dd><dt id="ty-check--help"><a href="#ty-check--help"><code>--help</code></a>, <code>-h</code></dt><dd><p>Print help (see a summary with '-h')</p>
</dd><dt id="ty-check--ignore"><a href="#ty-check--ignore"><code>--ignore</code></a> <i>rule</i></dt><dd><p>Disables the rule. Can be specified multiple times.</p>
</dd><dt id="ty-check--no-progress"><a href="#ty-check--no-progress"><code>--no-progress</code></a></dt><dd><p>Hide all progress outputs.</p>
<p>For example, spinners or progress bars.</p>
</dd><dt id="ty-check--output-format"><a href="#ty-check--output-format"><code>--output-format</code></a> <i>output-format</i></dt><dd><p>The format to use for printing diagnostic messages</p>
<p>Possible values:</p>
<ul>
<li><code>full</code>: Print diagnostics verbosely, with context and helpful hints (default)</li>
<li><code>concise</code>: Print diagnostics concisely, one per line</li>
<li><code>gitlab</code>: Print diagnostics in the JSON format expected by GitLab Code Quality reports</li>
<li><code>github</code>: Print diagnostics in the format used by GitHub Actions workflow error annotations</li>
</ul></dd><dt id="ty-check--project"><a href="#ty-check--project"><code>--project</code></a> <i>project</i></dt><dd><p>Run the command within the given project directory.</p>
<p>All <code>pyproject.toml</code> files will be discovered by walking up the directory tree from the given project directory, as will the project's virtual environment (<code>.venv</code>) unless the <code>venv-path</code> option is set.</p>
<p>Other command-line arguments (such as relative paths) will be resolved relative to the current working directory.</p>
</dd><dt id="ty-check--python"><a href="#ty-check--python"><code>--python</code></a>, <code>--venv</code> <i>path</i></dt><dd><p>Path to your project's Python environment or interpreter.</p>
<p>ty uses your Python environment to resolve third-party imports in your code.</p>
<p>If you're using a project management tool such as uv or you have an activated Conda or virtual environment, you should not generally need to specify this option.</p>
<p>This option can be used to point to virtual or system Python environments.</p>
</dd><dt id="ty-check--python-platform"><a href="#ty-check--python-platform"><code>--python-platform</code></a>, <code>--platform</code> <i>platform</i></dt><dd><p>Target platform to assume when resolving types.</p>
<p>This is used to specialize the type of <code>sys.platform</code> and will affect the visibility of platform-specific functions and attributes. If the value is set to <code>all</code>, no assumptions are made about the target platform. If unspecified, the current system's platform will be used.</p>
</dd><dt id="ty-check--python-version"><a href="#ty-check--python-version"><code>--python-version</code></a>, <code>--target-version</code> <i>version</i></dt><dd><p>Python version to assume when resolving types.</p>
<p>The Python version affects allowed syntax, type definitions of the standard library, and type definitions of first- and third-party modules that are conditional on the Python version.</p>
<p>If a version is not specified on the command line or in a configuration file, ty will try the following techniques in order of preference to determine a value: 1. Check for the <code>project.requires-python</code> setting in a <code>pyproject.toml</code> file and use the minimum version from the specified range 2. Check for an activated or configured Python environment and attempt to infer the Python version of that environment 3. Fall back to the latest stable Python version supported by ty (see <code>ty check --help</code> output)</p>
<p>Possible values:</p>
<ul>
<li><code>3.7</code></li>
<li><code>3.8</code></li>
<li><code>3.9</code></li>
<li><code>3.10</code></li>
<li><code>3.11</code></li>
<li><code>3.12</code></li>
<li><code>3.13</code></li>
<li><code>3.14</code></li>
</ul></dd><dt id="ty-check--quiet"><a href="#ty-check--quiet"><code>--quiet</code></a>, <code>-q</code></dt><dd><p>Use quiet output (or <code>-qq</code> for silent output)</p>
</dd><dt id="ty-check--respect-ignore-files"><a href="#ty-check--respect-ignore-files"><code>--respect-ignore-files</code></a></dt><dd><p>Respect file exclusions via <code>.gitignore</code> and other standard ignore files. Use <code>--no-respect-gitignore</code> to disable</p>
</dd><dt id="ty-check--typeshed"><a href="#ty-check--typeshed"><code>--typeshed</code></a>, <code>--custom-typeshed-dir</code> <i>path</i></dt><dd><p>Custom directory to use for stdlib typeshed stubs</p>
</dd><dt id="ty-check--verbose"><a href="#ty-check--verbose"><code>--verbose</code></a>, <code>-v</code></dt><dd><p>Use verbose output (or <code>-vv</code> and <code>-vvv</code> for more verbose output)</p>
</dd><dt id="ty-check--warn"><a href="#ty-check--warn"><code>--warn</code></a> <i>rule</i></dt><dd><p>Treat the given rule as having severity 'warn'. Can be specified multiple times.</p>
</dd><dt id="ty-check--watch"><a href="#ty-check--watch"><code>--watch</code></a>, <code>-W</code></dt><dd><p>Watch files for changes and recheck files related to the changed files</p>
</dd></dl>
## ty server
Start the language server
<h3 class="cli-reference">Usage</h3>
```
ty server
```
<h3 class="cli-reference">Options</h3>
<dl class="cli-reference"><dt id="ty-server--help"><a href="#ty-server--help"><code>--help</code></a>, <code>-h</code></dt><dd><p>Print help</p>
</dd></dl>
## ty version
Display ty's version
<h3 class="cli-reference">Usage</h3>
```
ty version
```
<h3 class="cli-reference">Options</h3>
<dl class="cli-reference"><dt id="ty-version--help"><a href="#ty-version--help"><code>--help</code></a>, <code>-h</code></dt><dd><p>Print help</p>
</dd></dl>
## ty generate-shell-completion
Generate shell completion
<h3 class="cli-reference">Usage</h3>
```
ty generate-shell-completion <SHELL>
```
<h3 class="cli-reference">Arguments</h3>
<dl class="cli-reference"><dt id="ty-generate-shell-completion--shell"><a href="#ty-generate-shell-completion--shell"><code>SHELL</code></a></dt></dl>
<h3 class="cli-reference">Options</h3>
<dl class="cli-reference"><dt id="ty-generate-shell-completion--help"><a href="#ty-generate-shell-completion--help"><code>--help</code></a>, <code>-h</code></dt><dd><p>Print help</p>
</dd></dl>
## ty help
Print this message or the help of the given subcommand(s)
<h3 class="cli-reference">Usage</h3>
```
ty help [COMMAND]
```
## /docs/reference/configuration.md
<!-- WARNING: This file is auto-generated (cargo dev generate-all). Update the doc comments on the 'Options' struct in 'crates/ty_project/src/metadata/options.rs' if you want to change anything here. -->
# Configuration
## `rules`
Configures the enabled rules and their severity.
See [the rules documentation](https://ty.dev/rules) for a list of all available rules.
Valid severities are:
* `ignore`: Disable the rule.
* `warn`: Enable the rule and create a warning diagnostic.
* `error`: Enable the rule and create an error diagnostic.
ty will exit with a non-zero code if any error diagnostics are emitted.
**Default value**: `{...}`
**Type**: `dict[RuleName, "ignore" | "warn" | "error"]`
**Example usage** (`pyproject.toml`):
```toml
[tool.ty.rules]
possibly-unresolved-reference = "warn"
division-by-zero = "ignore"
```
---
## `environment`
### `extra-paths`
User-provided paths that should take first priority in module resolution.
This is an advanced option that should usually only be used for first-party or third-party
modules that are not installed into your Python environment in a conventional way.
Use the `python` option to specify the location of your Python environment.
This option is similar to mypy's `MYPYPATH` environment variable and pyright's `stubPath`
configuration setting.
**Default value**: `[]`
**Type**: `list[str]`
**Example usage** (`pyproject.toml`):
```toml
[tool.ty.environment]
extra-paths = ["./shared/my-search-path"]
```
---
### `python`
Path to your project's Python environment or interpreter.
ty uses the `site-packages` directory of your project's Python environment
to resolve third-party (and, in some cases, first-party) imports in your code.
If you're using a project management tool such as uv, you should not generally need
to specify this option, as commands such as `uv run` will set the `VIRTUAL_ENV`
environment variable to point to your project's virtual environment. ty can also infer
the location of your environment from an activated Conda environment, and will look for
a `.venv` directory in the project root if none of the above apply.
Passing a path to a Python executable is supported, but passing a path to a dynamic executable
(such as a shim) is not currently supported.
This option can be used to point to virtual or system Python environments.
**Default value**: `null`
**Type**: `str`
**Example usage** (`pyproject.toml`):
```toml
[tool.ty.environment]
python = "./custom-venv-location/.venv"
```
---
### `python-platform`
Specifies the target platform that will be used to analyze the source code.
If specified, ty will understand conditions based on comparisons with `sys.platform`, such
as are commonly found in typeshed to reflect the differing contents of the standard library across platforms.
If `all` is specified, ty will assume that the source code can run on any platform.
If no platform is specified, ty will use the current platform:
- `win32` for Windows
- `darwin` for macOS
- `android` for Android
- `ios` for iOS
- `linux` for everything else
**Default value**: `<current-platform>`
**Type**: `"win32" | "darwin" | "android" | "ios" | "linux" | "all" | str`
**Example usage** (`pyproject.toml`):
```toml
[tool.ty.environment]
# Tailor type stubs and conditionalized type definitions to windows.
python-platform = "win32"
```
---
### `python-version`
Specifies the version of Python that will be used to analyze the source code.
The version should be specified as a string in the format `M.m` where `M` is the major version
and `m` is the minor (e.g. `"3.0"` or `"3.6"`).
If a version is provided, ty will generate errors if the source code makes use of language features
that are not supported in that version.
If a version is not specified, ty will try the following techniques in order of preference
to determine a value:
1. Check for the `project.requires-python` setting in a `pyproject.toml` file
and use the minimum version from the specified range
2. Check for an activated or configured Python environment
and attempt to infer the Python version of that environment
3. Fall back to the default value (see below)
For some language features, ty can also understand conditionals based on comparisons
with `sys.version_info`. These are commonly found in typeshed, for example,
to reflect the differing contents of the standard library across Python versions.
**Default value**: `"3.14"`
**Type**: `"3.7" | "3.8" | "3.9" | "3.10" | "3.11" | "3.12" | "3.13" | "3.14" | <major>.<minor>`
**Example usage** (`pyproject.toml`):
```toml
[tool.ty.environment]
python-version = "3.12"
```
---
### `root`
The root paths of the project, used for finding first-party modules.
Accepts a list of directory paths searched in priority order (first has highest priority).
If left unspecified, ty will try to detect common project layouts and initialize `root` accordingly:
* if a `./src` directory exists, include `.` and `./src` in the first party search path (src layout or flat)
* if a `./<project-name>/<project-name>` directory exists, include `.` and `./<project-name>` in the first party search path
* otherwise, default to `.` (flat layout)
Besides, if a `./python` or `./tests` directory exists and is not a package (i.e. it does not contain an `__init__.py` or `__init__.pyi` file),
it will also be included in the first party search path.
**Default value**: `null`
**Type**: `list[str]`
**Example usage** (`pyproject.toml`):
```toml
[tool.ty.environment]
# Multiple directories (priority order)
root = ["./src", "./lib", "./vendor"]
```
---
### `typeshed`
Optional path to a "typeshed" directory on disk for us to use for standard-library types.
If this is not provided, we will fallback to our vendored typeshed stubs for the stdlib,
bundled as a zip file in the binary
**Default value**: `null`
**Type**: `str`
**Example usage** (`pyproject.toml`):
```toml
[tool.ty.environment]
typeshed = "/path/to/custom/typeshed"
```
---
## `overrides`
Configuration override that applies to specific files based on glob patterns.
An override allows you to apply different rule configurations to specific
files or directories. Multiple overrides can match the same file, with
later overrides take precedence.
### Precedence
- Later overrides in the array take precedence over earlier ones
- Override rules take precedence over global rules for matching files
### Examples
```toml
# Relax rules for test files
[[tool.ty.overrides]]
include = ["tests/**", "**/test_*.py"]
[tool.ty.overrides.rules]
possibly-unresolved-reference = "warn"
# Ignore generated files but still check important ones
[[tool.ty.overrides]]
include = ["generated/**"]
exclude = ["generated/important.py"]
[tool.ty.overrides.rules]
possibly-unresolved-reference = "ignore"
```
### `exclude`
A list of file and directory patterns to exclude from this override.
Patterns follow a syntax similar to `.gitignore`.
Exclude patterns take precedence over include patterns within the same override.
If not specified, defaults to `[]` (excludes no files).
**Default value**: `null`
**Type**: `list[str]`
**Example usage** (`pyproject.toml`):
```toml
[[tool.ty.overrides]]
exclude = [
"generated",
"*.proto",
"tests/fixtures/**",
"!tests/fixtures/important.py" # Include this one file
]
```
---
### `include`
A list of file and directory patterns to include for this override.
The `include` option follows a similar syntax to `.gitignore` but reversed:
Including a file or directory will make it so that it (and its contents)
are affected by this override.
If not specified, defaults to `["**"]` (matches all files).
**Default value**: `null`
**Type**: `list[str]`
**Example usage** (`pyproject.toml`):
```toml
[[tool.ty.overrides]]
include = [
"src",
"tests",
]
```
---
### `rules`
Rule overrides for files matching the include/exclude patterns.
These rules will be merged with the global rules, with override rules
taking precedence for matching files. You can set rules to different
severity levels or disable them entirely.
**Default value**: `{...}`
**Type**: `dict[RuleName, "ignore" | "warn" | "error"]`
**Example usage** (`pyproject.toml`):
```toml
[[tool.ty.overrides]]
include = ["src"]
[tool.ty.overrides.rules]
possibly-unresolved-reference = "ignore"
```
---
## `src`
### `exclude`
A list of file and directory patterns to exclude from type checking.
Patterns follow a syntax similar to `.gitignore`:
- `./src/` matches only a directory
- `./src` matches both files and directories
- `src` matches files or directories named `src`
- `*` matches any (possibly empty) sequence of characters (except `/`).
- `**` matches zero or more path components.
This sequence **must** form a single path component, so both `**a` and `b**` are invalid and will result in an error.
A sequence of more than two consecutive `*` characters is also invalid.
- `?` matches any single character except `/`
- `[abc]` matches any character inside the brackets. Character sequences can also specify ranges of characters, as ordered by Unicode,
so e.g. `[0-9]` specifies any character between `0` and `9` inclusive. An unclosed bracket is invalid.
- `!pattern` negates a pattern (undoes the exclusion of files that would otherwise be excluded)
All paths are anchored relative to the project root (`src` only
matches `<project_root>/src` and not `<project_root>/test/src`).
To exclude any directory or file named `src`, use `**/src` instead.
By default, ty excludes commonly ignored directories:
- `**/.bzr/`
- `**/.direnv/`
- `**/.eggs/`
- `**/.git/`
- `**/.git-rewrite/`
- `**/.hg/`
- `**/.mypy_cache/`
- `**/.nox/`
- `**/.pants.d/`
- `**/.pytype/`
- `**/.ruff_cache/`
- `**/.svn/`
- `**/.tox/`
- `**/.venv/`
- `**/__pypackages__/`
- `**/_build/`
- `**/buck-out/`
- `**/dist/`
- `**/node_modules/`
- `**/venv/`
You can override any default exclude by using a negated pattern. For example,
to re-include `dist` use `exclude = ["!dist"]`
**Default value**: `null`
**Type**: `list[str]`
**Example usage** (`pyproject.toml`):
```toml
[tool.ty.src]
exclude = [
"generated",
"*.proto",
"tests/fixtures/**",
"!tests/fixtures/important.py" # Include this one file
]
```
---
### `include`
A list of files and directories to check. The `include` option
follows a similar syntax to `.gitignore` but reversed:
Including a file or directory will make it so that it (and its contents)
are type checked.
- `./src/` matches only a directory
- `./src` matches both files and directories
- `src` matches a file or directory named `src`
- `*` matches any (possibly empty) sequence of characters (except `/`).
- `**` matches zero or more path components.
This sequence **must** form a single path component, so both `**a` and `b**` are invalid and will result in an error.
A sequence of more than two consecutive `*` characters is also invalid.
- `?` matches any single character except `/`
- `[abc]` matches any character inside the brackets. Character sequences can also specify ranges of characters, as ordered by Unicode,
so e.g. `[0-9]` specifies any character between `0` and `9` inclusive. An unclosed bracket is invalid.
All paths are anchored relative to the project root (`src` only
matches `<project_root>/src` and not `<project_root>/test/src`).
`exclude` takes precedence over `include`.
**Default value**: `null`
**Type**: `list[str]`
**Example usage** (`pyproject.toml`):
```toml
[tool.ty.src]
include = [
"src",
"tests",
]
```
---
### `respect-ignore-files`
Whether to automatically exclude files that are ignored by `.ignore`,
`.gitignore`, `.git/info/exclude`, and global `gitignore` files.
Enabled by default.
**Default value**: `true`
**Type**: `bool`
**Example usage** (`pyproject.toml`):
```toml
[tool.ty.src]
respect-ignore-files = false
```
---
### `root`
> [!WARN] "Deprecated"
> This option has been deprecated. Use `environment.root` instead.
The root of the project, used for finding first-party modules.
If left unspecified, ty will try to detect common project layouts and initialize `src.root` accordingly:
* if a `./src` directory exists, include `.` and `./src` in the first party search path (src layout or flat)
* if a `./<project-name>/<project-name>` directory exists, include `.` and `./<project-name>` in the first party search path
* otherwise, default to `.` (flat layout)
Besides, if a `./tests` directory exists and is not a package (i.e. it does not contain an `__init__.py` file),
it will also be included in the first party search path.
**Default value**: `null`
**Type**: `str`
**Example usage** (`pyproject.toml`):
```toml
[tool.ty.src]
root = "./app"
```
---
## `terminal`
### `error-on-warning`
Use exit code 1 if there are any warning-level diagnostics.
Defaults to `false`.
**Default value**: `false`
**Type**: `bool`
**Example usage** (`pyproject.toml`):
```toml
[tool.ty.terminal]
# Error if ty emits any warning-level diagnostics.
error-on-warning = true
```
---
### `output-format`
The format to use for printing diagnostic messages.
Defaults to `full`.
**Default value**: `full`
**Type**: `full | concise`
**Example usage** (`pyproject.toml`):
```toml
[tool.ty.terminal]
output-format = "concise"
```
---
## /docs/reference/editor-settings.md
# Editor settings
The editor settings supported by ty's language server, as well as the settings specific to [ty's VS
Code extension][ty-vscode].
## `disableLanguageServices`
Whether to disable the language services for the ty language server like code completion, hover,
go to definition, etc.
This is useful if you want to use ty exclusively for type checking and want to use another language
server for features like code completion, hover, go to definition, etc.
**Default value**: `false`
**Type**: `boolean`
**Example usage**:
=== "VS Code"
```json
{
"ty.disableLanguageServices": true
}
```
=== "Neovim"
```lua
require('lspconfig').ty.setup({
settings = {
ty = {
disableLanguageServices = true,
},
},
})
-- For Neovim 0.11.0 and later:
vim.lsp.config('ty', {
settings = {
ty = {
disableLanguageServices = true,
},
},
})
```
=== "Zed"
```json
{
"lsp": {
"ty": {
"settings": {
"disableLanguageServices": true
}
}
}
}
```
______________________________________________________________________
## `python.ty.disableLanguageServices`
!!! warning "Deprecated"
This option has been deprecated. Use [`ty.disableLanguageServices`](#disablelanguageservices) instead.
Whether to disable the language services that ty provides like code completion, hover, go to
definition, etc.
This is useful if you want to use ty exclusively for type checking in combination with another
language server for features like code completion, hover, go to definition, etc.
**Default value**: `false`
**Type**: `boolean`
**Example usage**:
```json
{
"python.ty.disableLanguageServices": true
}
```
______________________________________________________________________
## `diagnosticMode`
Determines the scope of the diagnostics reported by the language server.
- `openFilesOnly`: Diagnostics are reported only for files that are currently open in the editor.
- `workspace`: Diagnostics are reported for all files in the workspace.
**Default value**: `"openFilesOnly"`
**Type**: `"workspace" | "openFilesOnly"`
**Example usage**:
=== "VS Code"
```json
{
"ty.diagnosticMode": "workspace"
}
```
=== "Neovim"
```lua
require('lspconfig').ty.setup({
settings = {
ty = {
diagnosticMode = 'workspace',
},
},
})
-- For Neovim 0.11.0 and later:
vim.lsp.config('ty', {
settings = {
ty = {
diagnosticMode = 'workspace',
},
},
})
```
=== "Zed"
```json
{
"lsp": {
"ty": {
"settings": {
"diagnosticMode": "workspace"
}
}
}
}
```
______________________________________________________________________
## `inlayHints`
These settings control the inline hints that ty provides in an editor.
### `variableTypes`
Whether to show the types of variables as inline hints.
**Default value**: `true`
**Type**: `boolean`
**Example usage**:
=== "VS Code"
```json
{
"ty.inlayHints.variableTypes": false
}
```
=== "Neovim"
```lua
require('lspconfig').ty.setup({
settings = {
ty = {
inlayHints = {
variableTypes = false,
},
},
},
})
-- For Neovim 0.11.0 and later:
vim.lsp.config('ty', {
settings = {
ty = {
inlayHints = {
variableTypes = false,
},
},
},
})
```
=== "Zed"
```json
{
"lsp": {
"ty": {
"settings": {
"inlayHints": {
"variableTypes": false
}
}
}
}
}
```
### `callArgumentNames`
Whether to show argument names in call expressions as inline hints.
**Default value**: `true`
**Type**: `boolean`
**Example usage**:
=== "VS Code"
```json
{
"ty.inlayHints.callArgumentNames": false
}
```
=== "Neovim"
```lua
require('lspconfig').ty.setup({
settings = {
ty = {
inlayHints = {
callArgumentNames = false,
},
},
},
})
-- For Neovim 0.11.0 and later:
vim.lsp.config('ty', {
settings = {
ty = {
inlayHints = {
callArgumentNames = false,
},
},
},
})
```
=== "Zed"
```json
{
"lsp": {
"ty": {
"settings": {
"inlayHints": {
"callArgumentNames": false
}
}
}
}
}
```
______________________________________________________________________
## `experimental`
These settings control the experimental language features that ty provides in an editor.
### `rename`
Whether to enable the experimental support for renaming symbols in the editor.
**Default value**: `false`
**Type**: `boolean`
**Example usage**:
=== "VS Code"
```json
{
"ty.experimental.rename": true
}
```
=== "Neovim"
```lua
require('lspconfig').ty.setup({
settings = {
ty = {
experimental = {
rename = true,
},
},
},
})
-- For Neovim 0.11.0 and later:
vim.lsp.config('ty', {
settings = {
ty = {
experimental = {
rename = true,
},
},
},
})
```
=== "Zed"
```json
{
"lsp": {
"ty": {
"settings": {
"experimental": {
"rename": true
}
}
}
}
}
```
### `autoImport`
Whether to enable the experimental support for auto-import code completions. Note that this feature
is currently under active development and may not work correctly or be gratuitously slow.
**Default value**: `false`
**Type**: `boolean`
**Example usage**:
=== "VS Code"
```json
{
"ty.experimental.autoImport": true
}
```
=== "Neovim"
```lua
require('lspconfig').ty.setup({
settings = {
ty = {
experimental = {
autoImport = true,
},
},
},
})
-- For Neovim 0.11.0 and later:
vim.lsp.config('ty', {
settings = {
ty = {
experimental = {
autoImport = true,
},
},
},
})
```
=== "Zed"
```json
{
"lsp": {
"ty": {
"settings": {
"experimental": {
"autoImport": true
}
}
}
}
}
```
______________________________________________________________________
## VS Code specific
The following settings are specific to [ty's VS Code extension][ty-vscode].
### `importStrategy`
Strategy for loading the `ty` executable.
- `fromEnvironment` finds ty in the environment, falling back to the bundled version
- `useBundled` uses the version bundled with the extension
**Default value**: `"fromEnvironment"`
**Type**: `"fromEnvironment" | "useBundled"`
**Example usage**:
```json
{
"ty.importStrategy": "useBundled"
}
```
______________________________________________________________________
### `interpreter`
A list of paths to Python interpreters. Even though this is a list, only the first interpreter is
used.
The interpreter path is used to find the `ty` executable when
[`ty.importStrategy`](#importstrategy) is set to `fromEnvironment`.
**Default value**: `[]`
**Type**: `string[]`
**Example usage**:
```json
{
"ty.interpreter": ["/home/user/.local/bin/python"]
}
```
______________________________________________________________________
### `path`
A list of path to `ty` executables.
The extension uses the first executable that exists. This setting takes precedence over the
[`ty.importStrategy`](#importstrategy) setting.
**Default value**: `[]`
**Type**: `string[]`
**Example usage**:
```json
{
"ty.path": ["/home/user/.local/bin/ty"]
}
```
______________________________________________________________________
### `trace.server`
The detail level at which messages between the language server and the editor (client) are logged.
This setting is useful for debugging issues with the language server. Refer to the [troubleshooting
guide](https://github.com/astral-sh/ty-vscode/blob/6cf16b4e87342a49f2bec1310a730cde8229e1d9/TROUBLESHOOTING.md)
in [ty's VS Code extension][ty-vscode] for more information.
**Default value**: `"off"`
**Type**: `"off" | "messages" | "verbose"`
**Example usage**:
```json
{
"ty.trace.server": "messages"
}
```
______________________________________________________________________
## Initialization options
The following settings are required when ty is initialized in an editor. These settings are
static so changing them requires restarting the editor to take effect.
For VS Code users, these settings are defined in the `ty.*` namespace as usual, but for other
editors, they would need to be provided in a separate field of the configuration that corresponds to
the initialization options. Refer to the examples below for how to set these options in different
editors.
### `logFile`
Path to the file to which the language server writes its log messages. By default, ty writes log messages to stderr.
**Default value**: `null`
**Type**: `string`
**Example usage**:
=== "VS Code"
```json
{
"ty.logFile": "/path/to/ty.log"
}
```
=== "Neovim"
```lua
require('lspconfig').ty.setup({
init_options = {
logFile = '/path/to/ty.log',
},
})
-- For Neovim 0.11.0 and later:
vim.lsp.config('ty', {
init_options = {
logFile = '/path/to/ty.log',
},
})
```
=== "Zed"
```json
{
"lsp": {
"ty": {
"initialization_options": {
"logFile": "/path/to/ty.log"
}
}
}
}
```
______________________________________________________________________
### `logLevel`
The log level to use for the language server.
**Default value**: `"info"`
**Type**: `"trace" | "debug" | "info" | "warn" | "error"`
**Example usage**:
=== "VS Code"
```json
{
"ty.logLevel": "debug"
}
```
=== "Neovim"
```lua
require('lspconfig').ty.setup({
init_options = {
logLevel = 'debug',
},
})
-- For Neovim 0.11.0 and later:
vim.lsp.config('ty', {
init_options = {
logLevel = 'debug',
},
})
```
=== "Zed"
```json
{
"lsp": {
"ty": {
"initialization_options": {
"logLevel": "debug"
}
}
}
}
```
[ty-vscode]: https://marketplace.visualstudio.com/items?itemName=astral-sh.ty
## /docs/reference/environment.md
# Environment variables
ty defines and respects the following environment variables:
### `TY_LOG`
If set, ty will use this value as the log level for its `--verbose` output.
Accepts any filter compatible with the `tracing_subscriber` crate.
For example:
- `TY_LOG=uv=debug` is the equivalent of `-vv` to the command line
- `TY_LOG=trace` will enable all trace-level logging.
See the [tracing documentation](https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html#example-syntax)
for more.
### `TY_LOG_PROFILE`
If set to `"1"` or `"true"`, ty will enable flamegraph profiling.
This creates a `tracing.folded` file that can be used to generate flame graphs
for performance analysis.
### `TY_MAX_PARALLELISM`
Specifies an upper limit for the number of tasks ty is allowed to run in parallel.
For example, how many files should be checked in parallel.
This isn't the same as a thread limit. ty may spawn additional threads
when necessary, e.g. to watch for file system changes or a dedicated UI thread.
## Externally-defined variables
ty also reads the following externally defined environment variables:
### `CONDA_DEFAULT_ENV`
Used to determine the name of the active Conda environment.
### `CONDA_PREFIX`
Used to detect the path of an active Conda environment.
If both `VIRTUAL_ENV` and `CONDA_PREFIX` are present, `VIRTUAL_ENV` will be preferred.
### `PYTHONPATH`
Adds additional directories to ty's search paths.
The format is the same as the shell’s PATH:
one or more directory pathnames separated by os appropriate pathsep
(e.g. colons on Unix or semicolons on Windows).
### `RAYON_NUM_THREADS`
Specifies an upper limit for the number of threads ty uses when performing work in parallel.
Equivalent to `TY_MAX_PARALLELISM`.
This is a standard Rayon environment variable.
### `VIRTUAL_ENV`
Used to detect an activated virtual environment.
### `XDG_CONFIG_HOME`
Path to user-level configuration directory on Unix systems.
### `_CONDA_ROOT`
Used to determine the root install path of Conda.
## /docs/reference/exit-codes.md
# Exit codes
The ty command line interface uses the following exit codes:
| Exit code | Description |
| :-------- | :------------------------------------------------------- |
| `0` | no violations with severity `error` or higher were found |
| `1` | violations with severity `error` or higher were found |
| `2` | invalid CLI options |
| `101` | internal error |
ty supports two command line arguments that change how exit codes work:
- `--exit-zero`: ty will exit with `0` even if violations were found.
- `--error-on-warning`: ty will exit with `1` if it finds any violations with severity `warning` or
higher.
## /docs/requirements-insiders.in
```in path="/docs/requirements-insiders.in"
-r requirements.in
mkdocs-material @ git+ssh://git@github.com/astral-sh/mkdocs-material-insiders.git@38c0b8187325c3bab386b666daf3518ac036f2f4
```
## /docs/requirements-insiders.txt
# This file was autogenerated by uv via the following command:
# uv pip compile docs/requirements-insiders.in -o docs/requirements-insiders.txt --universal -p 3.12
babel==2.15.0
# via
# mkdocs-git-revision-date-localized-plugin
# mkdocs-material
beautifulsoup4==4.13.4
# via
# markdownify
# mkdocs-llmstxt
black==23.10.0
# via -r docs/requirements.in
certifi==2024.7.4
# via requests
charset-normalizer==3.3.2
# via requests
click==8.1.7
# via
# black
# mkdocs
colorama==0.4.6
# via
# click
# mkdocs
# mkdocs-material
ghp-import==2.1.0
# via mkdocs
gitdb==4.0.12
# via gitpython
gitpython==3.1.44
# via mkdocs-git-revision-date-localized-plugin
idna==3.7
# via requests
jinja2==3.1.4
# via
# mkdocs
# mkdocs-material
linkify-it-py==2.0.3
# via markdown-it-py
markdown==3.6
# via
# mkdocs
# mkdocs-material
# pymdown-extensions
markdown-it-py==3.0.0
# via
# mdformat
# mdformat-gfm
# mdit-py-plugins
markdownify==1.1.0
# via mkdocs-llmstxt
markupsafe==2.1.5
# via
# jinja2
# mkdocs
mdformat==0.7.22
# via
# -r docs/requirements.in
# mdformat-admon
# mdformat-gfm
# mdformat-mkdocs
# mdformat-tables
# mkdocs-llmstxt
mdformat-admon==2.0.2
# via
# -r docs/requirements.in
# mdformat-mkdocs
mdformat-gfm==0.3.6
# via mdformat-mkdocs
mdformat-mkdocs==2.0.4
# via -r docs/requirements.in
mdformat-tables==0.4.1
# via mdformat-gfm
mdit-py-plugins==0.4.1
# via
# mdformat-admon
# mdformat-gfm
mdurl==0.1.2
# via markdown-it-py
mergedeep==1.3.4
# via
# mkdocs
# mkdocs-material
mkdocs==1.5.0
# via
# -r docs/requirements.in
# mkdocs-git-revision-date-localized-plugin
# mkdocs-material
# mkdocs-redirects
mkdocs-git-revision-date-localized-plugin==1.3.0
# via -r docs/requirements.in
mkdocs-llmstxt==0.2.0
# via -r docs/requirements.in
mkdocs-material @ git+ssh://git@github.com/astral-sh/mkdocs-material-insiders.git@38c0b8187325c3bab386b666daf3518ac036f2f4
# via
# -r docs/requirements-insiders.in
# -r docs/requirements.in
mkdocs-material-extensions==1.3.1
# via mkdocs-material
mkdocs-redirects==1.2.2
# via -r docs/requirements.in
more-itertools==10.3.0
# via mdformat-mkdocs
mypy-extensions==1.0.0
# via black
packaging==24.1
# via
# black
# mkdocs
paginate==0.5.6
# via mkdocs-material
pathspec==0.12.1
# via
# black
# mkdocs
platformdirs==4.2.2
# via
# black
# mkdocs
pygments==2.18.0
# via mkdocs-material
pymdown-extensions==10.8.1
# via mkdocs-material
python-dateutil==2.9.0.post0
# via ghp-import
pytz==2025.1
# via mkdocs-git-revision-date-localized-plugin
pyyaml==6.0.1
# via
# mkdocs
# pymdown-extensions
# pyyaml-env-tag
pyyaml-env-tag==0.1
# via mkdocs
regex==2022.10.31
# via mkdocs-material
requests==2.32.3
# via mkdocs-material
six==1.16.0
# via
# markdownify
# python-dateutil
smmap==5.0.2
# via gitdb
soupsieve==2.7
# via beautifulsoup4
typing-extensions==4.14.0
# via beautifulsoup4
uc-micro-py==1.0.3
# via linkify-it-py
urllib3==2.2.2
# via requests
watchdog==4.0.1
# via mkdocs
## /docs/requirements.in
```in path="/docs/requirements.in"
black>=23.10.0
mkdocs>=1.5.0
mkdocs-material>=9.1.18
mkdocs-redirects>=1.2.1
mdformat>=0.7.17
mdformat-mkdocs>=2.0.4
mdformat-admon>=2.0.2
mkdocs-redirects>=1.2.2
mkdocs-git-revision-date-localized-plugin>=1.3.0
mkdocs-llmstxt>=0.2.0
```
## /docs/requirements.txt
# This file was autogenerated by uv via the following command:
# uv pip compile docs/requirements.in -o docs/requirements.txt --universal -p 3.12
babel==2.15.0
# via
# mkdocs-git-revision-date-localized-plugin
# mkdocs-material
beautifulsoup4==4.13.4
# via
# markdownify
# mkdocs-llmstxt
black==24.4.2
# via -r docs/requirements.in
certifi==2024.7.4
# via requests
charset-normalizer==3.3.2
# via requests
click==8.1.7
# via
# black
# mkdocs
colorama==0.4.6
# via
# click
# mkdocs
# mkdocs-material
ghp-import==2.1.0
# via mkdocs
gitdb==4.0.12
# via gitpython
gitpython==3.1.44
# via mkdocs-git-revision-date-localized-plugin
idna==3.7
# via requests
jinja2==3.1.4
# via
# mkdocs
# mkdocs-material
linkify-it-py==2.0.3
# via markdown-it-py
markdown==3.6
# via
# mkdocs
# mkdocs-material
# pymdown-extensions
markdown-it-py==3.0.0
# via
# mdformat
# mdformat-gfm
# mdit-py-plugins
markdownify==1.1.0
# via mkdocs-llmstxt
markupsafe==2.1.5
# via
# jinja2
# mkdocs
mdformat==0.7.22
# via
# -r docs/requirements.in
# mdformat-admon
# mdformat-gfm
# mdformat-mkdocs
# mdformat-tables
# mkdocs-llmstxt
mdformat-admon==2.0.6
# via
# -r docs/requirements.in
# mdformat-mkdocs
mdformat-gfm==0.3.6
# via mdformat-mkdocs
mdformat-mkdocs==3.0.0
# via -r docs/requirements.in
mdformat-tables==0.4.1
# via mdformat-gfm
mdit-py-plugins==0.4.1
# via
# mdformat-admon
# mdformat-gfm
# mdformat-mkdocs
mdurl==0.1.2
# via markdown-it-py
mergedeep==1.3.4
# via
# mkdocs
# mkdocs-get-deps
mkdocs==1.6.0
# via
# -r docs/requirements.in
# mkdocs-git-revision-date-localized-plugin
# mkdocs-material
# mkdocs-redirects
mkdocs-get-deps==0.2.0
# via mkdocs
mkdocs-git-revision-date-localized-plugin==1.3.0
# via -r docs/requirements.in
mkdocs-llmstxt==0.2.0
# via -r docs/requirements.in
mkdocs-material==9.5.29
# via -r docs/requirements.in
mkdocs-material-extensions==1.3.1
# via mkdocs-material
mkdocs-redirects==1.2.2
# via -r docs/requirements.in
more-itertools==10.3.0
# via mdformat-mkdocs
mypy-extensions==1.0.0
# via black
packaging==24.1
# via
# black
# mkdocs
paginate==0.5.6
# via mkdocs-material
pathspec==0.12.1
# via
# black
# mkdocs
platformdirs==4.2.2
# via
# black
# mkdocs-get-deps
pygments==2.18.0
# via mkdocs-material
pymdown-extensions==10.8.1
# via mkdocs-material
python-dateutil==2.9.0.post0
# via ghp-import
pytz==2025.1
# via mkdocs-git-revision-date-localized-plugin
pyyaml==6.0.1
# via
# mkdocs
# mkdocs-get-deps
# pymdown-extensions
# pyyaml-env-tag
pyyaml-env-tag==0.1
# via mkdocs
regex==2024.5.15
# via mkdocs-material
requests==2.32.3
# via mkdocs-material
six==1.16.0
# via
# markdownify
# python-dateutil
smmap==5.0.2
# via gitdb
soupsieve==2.7
# via beautifulsoup4
typing-extensions==4.14.0
# via beautifulsoup4
uc-micro-py==1.0.3
# via linkify-it-py
urllib3==2.2.2
# via requests
watchdog==4.0.1
# via mkdocs
## /docs/rules.md
# Rules
Rules are individual checks that ty performs to detect common issues in your code, such as
incompatible assignments, missing imports, or invalid type annotations. Each rule focuses on a
specific pattern and can be turned on or off depending on your project’s needs.
!!! tip
See [rules](./reference/rules.md) for an enumeration of all supported rules.
## Rule levels
Each rule has a configurable level:
- `error`: violations are reported as errors and ty exits with an exit code of 1 if there's any.
- `warn`: violations are reported as warnings. Depending on your configuration, ty exits with an exit code of 0 if there are only warning violations (default) or 1 when using `--error-on-warning`.
- `ignore`: the rule is turned off
You can configure the level for each rule on the command line using the `--warn`, `--error`, and
`--ignore` flags. For example:
```shell
ty check \
--warn unused-ignore-comment \ # Make `unused-ignore-comment` a warning
--ignore redundant-cast \ # Disable `redundant-cast`
--error possibly-missing-attribute \ # Error on `possibly-missing-attribute`
--error possibly-missing-import # Error on `possibly-missing-import`
```
The options can be repeated. Subsequent options override earlier options.
Rule levels can also be changed in the [`rules`](./reference/configuration.md#rules) section of a
[configuration file](./configuration.md).
For example, the following is equivalent to the command above:
```toml
[tool.ty.rules]
unused-ignore-comment = "warn"
redundant-cast = "ignore"
possibly-missing-attribute = "error"
possibly-missing-import = "error"
```
## /mkdocs.insiders.yml
```yml path="/mkdocs.insiders.yml"
INHERIT: mkdocs.template.yml
watch:
- mkdocs.template.yml
```
## /mkdocs.public.yml
```yml path="/mkdocs.public.yml"
# NOTE: Usually, you should edit the template instead.
# This file is used for forks and contributors, production uses `mkdocs.insiders.yml`.
INHERIT: mkdocs.template.yml
watch:
- mkdocs.template.yml
```
## /python/ty/__init__.py
```py path="/python/ty/__init__.py"
```
## /python/ty/py.typed
```typed path="/python/ty/py.typed"
```
## /scripts/autogenerate_files.sh
```sh path="/scripts/autogenerate_files.sh"
#!/usr/bin/env sh
#
# Generate files and copy documentation from Ruff.
#
# Usage
#
# ./scripts/autogenerate-files.sh
#
set -eu
script_root="$(realpath "$(dirname "$0")")"
project_root="$(dirname "$script_root")"
cd "$project_root"
echo "Updating lockfile..."
uv lock
echo "Copying reference documentation from Ruff..."
cp ./ruff/crates/ty/docs/cli.md ./docs/reference/
cp ./ruff/crates/ty/docs/configuration.md ./docs/reference/
cp ./ruff/crates/ty/docs/rules.md ./docs/reference/
cp ./ruff/crates/ty/docs/environment.md ./docs/reference/
echo "Documentation has been copied from Ruff submodule"
```
The content has been capped at 50000 tokens. The user could consider applying other filters to refine the result. The better and more specific the context, the better the LLM can follow instructions. If the context seems verbose, the user can refine the filter using uithub. Thank you for using https://uithub.com - Perfect LLM context for any GitHub repo.