Moving Beyond Mypy: Why ty is the Future of Python Type Checking
You've pointed out ty (from the Astral team, the creators of uv and ruff). If you’ve used their other tools, you know their mantra
Rust-powered speed.
Here is a breakdown of why this is a game-changer for Python developers, how to get started, and what it looks like in practice.
In the Python ecosystem, we’ve traditionally relied on tools like mypy or pyright for type checking. While powerful, they can sometimes feel sluggish on massive codebases.
ty is designed to be
Blazing Fast
Since it's written in Rust, it aims to provide near-instant feedback, even as your project grows.
Integrated
It’s not just a checker; it’s a Language Server (LSP). This means your IDE (like VS Code) gets real-time "red squiggly lines" without the lag.
Correctness at Scale
It helps catch those pesky TypeError bugs before they ever reach production, which is crucial for maintaining high-quality software.
Since this is an Astral project, the easiest way to manage it is via uv, but you can also use standard pip.
Open your terminal and run
# Using uv (Recommended for speed)
uv tool install astral-sh/ty
# Or using pip
pip install ty
You can run it directly against your files or directory
ty check .
Let's look at a typical scenario where ty saves the day. Imagine you are building a simple service to calculate user discounts.
Without a type checker, this code might pass a simple test but fail later
def apply_discount(price: float, discount: float) -> float:
return price - (price * discount)
# Oops! Someone passed a string by mistake
print(apply_discount(100.0, "0.1"))
When you run ty check, it will immediately flag the error
error: Argument of type "str" cannot be assigned to parameter "discount" of type "float"
Here is how we write it to be "type-safe," allowing ty to give us the green light
from typing import List, Optional
def get_total_price(prices: List[float], tax_rate: Optional[float] = None) -> float:
total = sum(prices)
if tax_rate:
total += total * tax_rate
return total
# Valid usage
items = [19.99, 5.50, 10.0]
print(f"Total: ${get_total_price(items, tax_rate=0.08)}")
To truly feel the power of ty, you should use it as your Language Server.
VS Code
You can point your Python LSP settings to use ty (or the underlying red-knot engine it's built on) to get instant feedback as you type.
CI/CD
Add ty check . to your GitHub Actions. Because it's so fast, it won't slow down your PR checks!
ty is essentially Ruff for Type Checking. It removes the "waiting" period from the development cycle, allowing you to stay in the "flow state" longer while ensuring your Python code is robust and well-typed.