Open-Source Wikis

/

Ruff

/

Crates

/

`ty_python_semantic`

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
  • TypeGuard and TypeIs
  • Decorators that affect type (@dataclass, @final, @overload)
  • TypedDict, NamedTuple, Enum
  • PEP 695 type aliases
  • 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

Modifying

  • New type-check rule: add a LintMetadata entry, implement the check (typically in types/<area>.rs or lint.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-all to keep ty.schema.json in 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.

`ty_python_semantic` – Ruff wiki | Factory