Skip to content

monty-type-checking

Type checking for Monty sessions, powered by ty: checks code against Monty’s trimmed typeshed before execution.

ImportedModule

pub struct ImportedModule {
    pub name: String,
    /// The first import statement naming it.
    pub range: ruff_text_size::TextRange,
}

A top-level module a snippet imports (a for import a.b and from a.b import c).

Implements: Debug, Eq, PartialEq, StructuralPartialEq.

SnippetImports

pub struct SnippetImports {
    /// Import statements with aliases, one per line, injected before later checks' `.pyi` star import.
    /// This preserves bindings such as `import math`, which `.pyi` files do not re-export.
    pub prelude: String,
    /// Each top-level module imported, once, in source order.
    pub modules: Vec<ImportedModule>,
}

Imports collected by scan_imports.

Implements: Debug, Default, Eq, PartialEq, StructuralPartialEq.

scan_imports

pub fn scan_imports(source: &str) -> SnippetImports;

Collects imports outside function and class bodies, excluding __future__ and relative imports. Invalid syntax yields no imports. All module-level branches are included because the checker cannot tell which ran, and any names bound at runtime must resolve.

SourceFile

pub struct SourceFile<'a> {
    /// source code
    pub source_code: &'a str,
    /// file path
    pub path: &'a str,
}

Definition of a source file.

new

pub fn new(source_code: &'a str, path: &'a str) -> Self

Create a new source file.

Implements: Clone, Copy, Debug.

TypeCheckContext

pub struct TypeCheckContext<'a> {
    /// Host stubs and committed snippets, star-imported into the snippet.
    pub stubs: Option<&'a SourceFile<'a>>,
    /// Host module stubs, written as `.pyi` modules or packages and never star-imported.
    pub module_stubs: &'a [monty_types::ModuleStub],
    /// Committed imports injected before the star import; see `scan_imports`.
    pub prelude: &'a str,
}

Session declarations and imports for TypeChecker::run_with.

Implements: Clone, Copy, Debug, Default.

TypeChecker

pub struct TypeChecker { /* private fields */ }

run

pub fn run<'a>(
    &'a mut self,
    python_source: &SourceFile<'_>,
    stubs_file: Option<&SourceFile<'_>>,
    config: TypeCheckingConfig,
) -> Result<Option<TypeCheckingDiagnostics<'a>>, String>

Type check some python source code, checking if it’s valid to run with monty.

Arguments

  • python_source - The python source code to type check.
  • stubs_file - Optional stubs file to use for type checking.
  • config - Configuration for the type checking diagnostics.

Returns

  • Ok(None) - If there are no typing errors.
  • Ok(Some(string)) - If there are typing errors.
  • Err(String) - If there was an unexpected/internal error during type checking, or the script path names the stubs file.

run_with

pub fn run_with<'a>(
    &'a mut self,
    python_source: &SourceFile<'_>,
    context: &TypeCheckContext<'_>,
    config: TypeCheckingConfig,
) -> Result<Option<TypeCheckingDiagnostics<'a>>, String>

run with host module stubs and committed imports. The prelude precedes the stubs’ star import so later bindings shadow imports as at runtime. Diagnostics use the snippet’s original line numbers.

reset

pub fn reset(&mut self) -> Result<(), String>

Remove every file written since the last reset and sync the filesystem changes, so the checker can be reused for unrelated code.

Security-critical: without this a recycled worker would let one session’s modules and stubs resolve while checking the next session’s code. Each TouchedRootFile::cleanup removes its own file and walks its ancestor chain up to SRC_ROOT, removing any directory that has become empty. Shared parent directories collapse naturally once the last file inside them is gone. We sync SRC_ROOT once at the end so the next session cannot observe the previous root directory listing.

Implements: Debug, Default.

TypeCheckingDiagnostics

pub struct TypeCheckingDiagnostics<'a> { /* private fields */ }

The diagnostics of one failed type check, rendered on Display.

Borrows the checker because ty’s diagnostics only resolve their spans (file paths, source snippets) against the database that produced them — which is why the format is chosen up front, in TypeChecker::run, and why callers that outlive the checker (anything across a process boundary) must keep the rendered string rather than this.

Implements: Display.