An extremely fast Python type checker and language server, written in Rust.
npx @tessl/cli install tessl/pypi-ty@0.0.0An extremely fast Python type checker and language server written in Rust. ty provides comprehensive type checking for Python codebases with advanced error reporting, configuration options, and Language Server Protocol support for seamless editor integration.
pip install ty or uv tool install ty or pipx install tyThe ty package can be imported as a Python module but provides minimal programmatic API:
import tyHowever, ty is primarily used as a command-line tool:
ty check# Basic type checking
ty check
# Check specific files
ty check src/main.py tests/
# Watch mode with auto-recheck
ty check --watch
# Use specific Python version
ty check --python-version 3.11
# Start language server
ty serverFor project integration:
# Add to project as dev dependency
uv add --dev ty
# Run with uv
uv run ty checkty consists of several key components:
The architecture prioritizes performance through Rust implementation while maintaining compatibility with Python tooling and ecosystems.
Core command-line functionality for type checking, language server operation, and tool management.
# Main command
ty <COMMAND>
# Type checking
ty check [OPTIONS] [PATHS]...
# Language server
ty server
# Version information
ty version
# Shell completion
ty generate-shell-completion <SHELL>
# Help
ty help [COMMAND]Arguments:
PATHS: List of files or directories to check (optional, defaults to project root)SHELL: Shell type for completion generation (bash, zsh, fish, powershell, elvish)COMMAND: Subcommand to get help for (optional)Global Options for ty check:
File and path options:
--project <project>: Run within specific project directory--exclude <exclude>: Glob patterns to exclude from checkingPython environment options:
--python <path>: Path to Python environment or interpreter. ty uses this to resolve type information and third-party dependencies. If not specified, ty attempts to infer from VIRTUAL_ENV/CONDA_PREFIX or discover .venv directory. If interpreter path is provided (e.g., .venv/bin/python3), ty attempts to find environment two directories up. Does not invoke interpreter, so won't resolve dynamic executables like shims.--python-version <version>, --target-version <version>: Target Python version (3.7-3.13). If not specified, ty tries: 1) project.requires-python in pyproject.toml, 2) infer from Python environment, 3) fallback to 3.13--python-platform <platform>, --platform <platform>: Target platform (win32/darwin/linux/android/ios/all). Used to specialize sys.platform type. If 'all', no platform assumptions are made. Defaults to current system platform.--extra-search-path <path>: Additional module resolution paths (can be repeated)--typeshed <path>, --custom-typeshed-dir <path>: Custom typeshed directory for standard library typesConfiguration options:
--config-file <path>: Path to ty.toml configuration file--config <config-option>, -c <config-option>: TOML key=value configuration overrideRule control options:
--error <rule>: Treat rule as error-level (can be repeated)--warn <rule>: Treat rule as warning-level (can be repeated)--ignore <rule>: Disable rule (can be repeated)Output options:
--output-format <format>: Message format (full/concise)--color <when>: Color output control (auto/always/never)--quiet/-q: Quiet output (use -qq for silent)--verbose/-v: Verbose output (use -vv, -vvv for more verbose)--help/-h: Print help informationBehavior options:
--watch/-W: Watch mode for continuous checking--error-on-warning: Exit code 1 on warnings--exit-zero: Always exit with code 0--respect-ignore-files: Respect file exclusions via .gitignore and other standard ignore files (use --no-respect-gitignore to disable)Limited programmatic access through Python module wrapper.
def find_ty_bin() -> str:
"""
Return the ty binary path.
Searches various installation locations including:
- System scripts directory
- User-specific installation paths
- Virtual environment paths
- pip build environments
- Adjacent bin directories
Returns:
str: Absolute path to ty binary executable
Raises:
FileNotFoundError: If ty binary cannot be located
"""Usage Example:
from ty import find_ty_bin
import subprocess
# Get ty binary path
ty_path = find_ty_bin()
# Run type checking programmatically
result = subprocess.run([ty_path, "check", "src/"], capture_output=True, text=True)
print(result.stdout)Comprehensive TOML-based configuration supporting project-level and user-level settings.
# pyproject.toml format
[tool.ty.rules]
rule_name = "ignore" | "warn" | "error"
[tool.ty.environment]
extra-paths = ["./shared/my-search-path"]
python = "./.venv"
python-platform = "win32" | "darwin" | "android" | "ios" | "linux" | "all"
python-version = "3.7" | "3.8" | "3.9" | "3.10" | "3.11" | "3.12" | "3.13"
root = ["./src", "./lib"]
typeshed = "/path/to/custom/typeshed"
[tool.ty.src]
include = ["src", "tests"]
exclude = ["generated", "*.proto", "tests/fixtures/**"] # Additional excludes beyond defaults
respect-ignore-files = true
[tool.ty.terminal]
output-format = "full" | "concise"
error-on-warning = false
[[tool.ty.overrides]]
include = ["tests/**"]
exclude = ["tests/fixtures/**"]
[tool.ty.overrides.rules]
rule_name = "ignore" | "warn" | "error"Configuration File Locations:
pyproject.toml (under [tool.ty]) or ty.toml~/.config/ty/ty.toml or $XDG_CONFIG_HOME/ty/ty.toml (Linux/macOS)%APPDATA%\ty\ty.toml (Windows)Precedence: Command line > project config > user config
Language server implementation providing real-time type checking and editor integration.
# Start language server
ty serverLSP Features:
Editor Integration:
VS Code:
{
"ty.enable": true,
"ty.path": "/path/to/ty",
"ty.settings": {
"python-version": "3.11"
}
}Neovim (nvim-lspconfig):
require('lspconfig').ty.setup({
settings = {
ty = {
-- ty language server settings
}
}
})Neovim 0.11+ (vim.lsp.config):
vim.lsp.config('ty', {
settings = {
ty = {
-- ty language server settings
}
}
})
vim.lsp.enable('ty')Environment variables that control ty's behavior and configuration.
# Configuration file path
export TY_CONFIG_FILE="/path/to/ty.toml"
# Python environment detection
export VIRTUAL_ENV="/path/to/venv"
export CONDA_PREFIX="/path/to/conda/env"Environment Variables:
TY_CONFIG_FILE: Override configuration file locationVIRTUAL_ENV: Active virtual environment path (auto-detected)CONDA_PREFIX: Conda environment path (auto-detected)ty uses standard exit codes to indicate the result of operations.
# Exit codes
0 # Success (no errors, or only warnings without --error-on-warning)
1 # Type errors found, or warnings with --error-on-warning
2 # Configuration or runtime errorsty implements sophisticated module resolution for Python projects:
src/ directories by defaultenvironment.root settingtests/ if it's not a packagesite-packages directories--python or auto-discovery via VIRTUAL_ENV/CONDA_PREFIX--typeshed optionty provides a comprehensive rule system for type checking configuration:
[tool.ty.rules]
# Examples of common rules
possibly-unresolved-reference = "warn"
division-by-zero = "ignore"
index-out-of-bounds = "error"
redundant-cast = "ignore"
unused-ignore-comment = "warn"# File-specific rule overrides
[[tool.ty.overrides]]
include = ["tests/**", "**/test_*.py"]
[tool.ty.overrides.rules]
possibly-unresolved-reference = "ignore" # Relax for teststy is optimized for speed and efficiency:
# GitHub Actions example
- name: Type check with ty
run: |
uv tool install ty
ty check --error-on-warning# .pre-commit-config.yaml
repos:
- repo: https://github.com/astral-sh/ty
rev: v0.0.1-alpha.20
hooks:
- id: ty# Development commands
ty check --watch # Continuous checking
ty check --verbose # Detailed output
ty check src/ tests/ # Specific paths
ty check --python .venv # Specific environment# Configuration types (for reference)
RuleName = str # Rule identifier (e.g., "possibly-unresolved-reference")
Severity = "ignore" | "warn" | "error"
PythonVersion = "3.7" | "3.8" | "3.9" | "3.10" | "3.11" | "3.12" | "3.13"
Platform = "win32" | "darwin" | "android" | "ios" | "linux" | "all"
OutputFormat = "full" | "concise"
ColorOption = "auto" | "always" | "never"
# Path specifications
Path = str # File or directory path
GlobPattern = str # Gitignore-style pattern