astral-sh/ruff
ty_python_semantic
ty's type system, inference engine, and built-in lints. Source: crates/ty_python_semantic/.
Purpose
Given a Salsa Database, this crate answers:
- What is the inferred type of expression e in file f?
- Does this assignment violate a declared annotation?
- Is this call compatible with the callee's signature?
- Are there protocol / structural type incompatibilities?
- … and produces diagnostics for any check that fails.
It is by far the largest ty crate.
Directory layout
crates/ty_python_semantic/src/
├── lib.rs
├── db.rs # Database trait and ProjectDatabase
├── place.rs
├── pull_types.rs
├── reachability.rs
├── semantic_model.rs
├── subscript.rs
├── dunder_all.rs
├── fixes.rs
├── lint.rs # registry + emit machinery
├── diagnostic/ # diagnostic types
├── suppression.rs / suppression/
├── types.rs / types/ # the type system itself
└── resources/mdtest/ # the giant mdtest fixture set (lives in resources)Key abstractions
| Type | Purpose |
|---|---|
Type |
The internal representation of a Python type (Class, Instance, Union, Intersection, Callable, Protocol, …). |
Db (trait alias) |
The trait every consumer of this crate works against. |
infer_definition_types, infer_expression_type |
The two big tracked queries. |
LintMetadata, LintId |
Registry of all type-check rules. |
Suppression |
# type: ignore[...] style suppressions. |
SemanticModel |
A façade similar to Ruff's, but on top of the Salsa database. |
Type system features
The crate implements (in various states of completeness):
- Nominal classes and instances, including generics
- Protocols (structural subtyping)
- Unions / intersections
- Literal types (
Literal["x"],Literal[1], …) - Tuples (homogeneous and heterogeneous)
- Callables and function overloads
- Generics:
TypeVar,ParamSpec,TypeVarTuple, variance, defaults - Type narrowing through
isinstance, equality,is, structural patterns TypeGuardandTypeIs- Decorators that affect type (
@dataclass,@final,@overload) TypedDict,NamedTuple,Enum- PEP 695
typealiases - Gradual typing (
Any,Never, partial unknowns)
The types/ subdirectory has one module per type kind / inference area. Browse it for the canonical implementation patterns.
Lints
lint.rs defines the registry of diagnostics emitted by the type checker (e.g. invalid-assignment, unsupported-operator, protocol-violation, call-non-callable, missing-return, …). Each diagnostic has a stable identifier, a default severity, and rich metadata that ends up in --explain and ty.schema.json.
mdtest
The mdtest corpus under resources/mdtest/ is the de facto specification for ty's behavior. Every type-system feature has at least one Markdown file documenting examples and expected diagnostics. Reading these files is often the fastest way to understand a behavior.
To run a single mdtest:
cargo nextest run -p ty_python_semantic -- mdtest::<relative/path/to/file.md>Integration points
- Built on top of
ruff_db(Database,File,System). - Consumes
ruff_python_parser,ruff_python_ast,ruff_python_semantic,ty_module_resolver,ty_vendored,ty_site_packages. - Consumed by
tyCLI,ty_server,ty_ide,ty_wasm.
Modifying
- New type-check rule: add a
LintMetadataentry, implement the check (typically intypes/<area>.rsorlint.rs), add an mdtest fixture, regenerate the schema. - New type-system feature: usually requires changes in
types/plus careful attention to tracked-query boundaries. - Always re-run
cargo dev generate-allto keepty.schema.jsonin sync.
See features/type-checker for the user-facing perspective and overview/architecture for how this crate sits in the bigger picture.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.