Skip to main content
Monty includes ty, a modern Python type checker from Astral, built directly into the binary. This allows you to catch type errors before code execution.

Basic Type Checking

Call type_check() on a Monty instance to verify types:
Output:

Enable at Construction

Pass type_check=True to enable type checking when creating a Monty instance:
Type checking is disabled by default. This allows you to run code that may not type-check perfectly but works at runtime.

Type Stubs for External Functions

When your code uses external functions or input variables, provide type stubs to help the type checker:

Input Variables

Declare input variables in type stubs:

Complex Type Definitions

Type stubs are only used for type checking. They don’t affect runtime behavior or provide default values.

Type Checking Function Definitions

Monty validates function return types:
Output:

Undefined Variables

Type checking catches references to undefined variables:
Output:

Display Formats

Control how type errors are displayed:

Full Format (Default)

Concise Format

Output:

Type and Message Only

Output:

JavaScript Display Options

Catching Type Errors

MontyTypingError is a subclass of MontyError:

Prefix Code in Manual Type Checking

You can provide prefix code when calling type_check() manually:
Use prefix_code parameter for one-off type checks. For construction-time type checking, use type_check_stubs instead.

Type Checking with Async Code

Type checking works with async functions:

Best Practices

1

Use type hints

Add type hints to your function definitions for better error messages:
2

Provide comprehensive stubs

Include all external functions and input variables in your type stubs:
3

Enable early for LLM code

Use type_check=True during construction to catch errors before execution:
4

Handle type errors gracefully

Catch MontyTypingError and provide feedback to your LLM or user:
Type checking does not guarantee runtime correctness. It catches many common errors but cannot prevent all runtime issues (e.g., division by zero, logic errors).

When to Skip Type Checking

Type checking is disabled by default because:
  1. Dynamic code patterns: Some valid runtime patterns don’t type check
  2. Rapid prototyping: Type checking adds overhead during development
  3. Partial type coverage: Not all code paths may have complete type information
You can skip type checking and rely on runtime validation when:
  • Code is simple and well-tested
  • Performance is critical
  • You’re using dynamic patterns that are hard to type

Next Steps

External Functions

Learn how to define external function type stubs

Error Handling

Handle runtime errors and exceptions