Monty provides a hierarchy of exception classes for different types of errors that can occur during code parsing, type checking, and execution.
Exception Hierarchy
MontyError (base exception)
├── MontySyntaxError
├── MontyTypingError
└── MontyRuntimeError
MontyError
Base exception for all Monty interpreter errors. Catching MontyError will catch syntax, runtime, and typing errors from Monty. This exception is raised internally by Monty and cannot be constructed directly.
Methods
exception()
def exception(self) -> BaseException
Returns the inner exception as a Python exception object.
The underlying Python exception
__str__()
Returns the exception message.
The exception message string
Example
import pydantic_monty
try:
m = pydantic_monty.Monty('invalid syntax [')
except pydantic_monty.MontyError as e:
print(f"Monty error: {e}")
inner = e.exception()
print(f"Inner exception type: {type(inner).__name__}")
MontySyntaxError
Raised when Python code has syntax errors or cannot be parsed by Monty.
Inherits exception() and __str__() from MontyError.
Methods
display()
def display(self, format: Literal['type-msg', 'msg'] = 'msg') -> str
Returns formatted exception string.
format
Literal['type-msg', 'msg']
default:"'msg'"
'type-msg': Returns 'ExceptionType: message' format
'msg': Returns just the message
Example
import pydantic_monty
try:
m = pydantic_monty.Monty('def broken(')
except pydantic_monty.MontySyntaxError as e:
print(e.display(format='type-msg'))
# Output: SyntaxError: Expected ')', found end of file
print(e.display(format='msg'))
# Output: Expected ')', found end of file
MontyTypingError
Raised when type checking finds errors in the code. This exception is raised when static type analysis detects type errors before execution.
Inherits exception() and __str__() from MontyError. Cannot be constructed directly from Python.
Methods
display()
def display(
self,
format: Literal[
'full', 'concise', 'azure', 'json', 'jsonlines',
'rdjson', 'pylint', 'gitlab', 'github'
] = 'full',
color: bool = False,
) -> str
Renders the type error diagnostics with the specified format and color.
format
Literal['full', 'concise', 'azure', 'json', 'jsonlines', 'rdjson', 'pylint', 'gitlab', 'github']
default:"'full'"
Output format for the diagnostics:
'full': Complete diagnostic output with context
'concise': Abbreviated diagnostic output
'azure': Azure Pipelines format
'json': JSON format
'jsonlines': JSON Lines format
'rdjson': Reviewdog JSON format
'pylint': Pylint format
'gitlab': GitLab CI format
'github': GitHub Actions format
Whether to include ANSI color codes in the output
Formatted type error diagnostics
Example
import pydantic_monty
code = """
def add(x: int, y: int) -> int:
return x + y
result: str = add(1, 2)
"""
try:
m = pydantic_monty.Monty(code, type_check=True)
except pydantic_monty.MontyTypingError as e:
# Full format with color
print(e.display(format='full', color=True))
# Concise format without color
print(e.display(format='concise', color=False))
# JSON format for tooling
import json
diagnostics = json.loads(e.display(format='json'))
print(diagnostics)
MontyRuntimeError
Raised when Monty code fails during execution.
Inherits exception() and __str__() from MontyError. Additionally provides traceback() and display() methods.
Methods
traceback()
def traceback(self) -> list[Frame]
Returns the Monty traceback as a list of Frame objects.
List of stack frames showing the call stack at the time of the error
display()
def display(
self,
format: Literal['traceback', 'type-msg', 'msg'] = 'traceback'
) -> str
Returns formatted exception string.
format
Literal['traceback', 'type-msg', 'msg']
default:"'traceback'"
'traceback': Full traceback with exception
'type-msg': 'ExceptionType: message' format
'msg': Just the message
Example
import pydantic_monty
code = """
def divide(a, b):
return a / b
result = divide(10, 0)
"""
m = pydantic_monty.Monty(code)
try:
m.run()
except pydantic_monty.MontyRuntimeError as e:
# Display full traceback
print(e.display(format='traceback'))
# Output:
# Traceback (most recent call last):
# File "main.py", line 5, in <module>
# result = divide(10, 0)
# File "main.py", line 2, in divide
# return a / b
# ZeroDivisionError: division by zero
# Display just type and message
print(e.display(format='type-msg'))
# Output: ZeroDivisionError: division by zero
# Get programmatic access to traceback
frames = e.traceback()
for frame in frames:
print(f"{frame.filename}:{frame.line} in {frame.function_name}")
Frame
A single frame in a Monty traceback. This class provides detailed information about a specific point in the call stack.
Properties
The filename where the code is located
End line number (1-based)
End column number (1-based)
The name of the function, or None for module-level code
The source code line for preview in the traceback
Methods
dict()
def dict(self) -> dict[str, int | str | None]
Returns a dictionary of all frame attributes.
Dictionary containing all frame properties
Example
import pydantic_monty
code = """
def outer():
inner()
def inner():
raise ValueError('Something went wrong')
outer()
"""
m = pydantic_monty.Monty(code)
try:
m.run()
except pydantic_monty.MontyRuntimeError as e:
frames = e.traceback()
for frame in frames:
print(f"File: {frame.filename}")
print(f"Line: {frame.line}, Column: {frame.column}")
print(f"Function: {frame.function_name}")
print(f"Source: {frame.source_line}")
print(f"Dict: {frame.dict()}")
print("---")
Error Handling Best Practices
Catch Specific Exceptions
import pydantic_monty
code = "x = 1 / 0"
try:
m = pydantic_monty.Monty(code)
result = m.run()
except pydantic_monty.MontySyntaxError as e:
print(f"Syntax error: {e}")
except pydantic_monty.MontyTypingError as e:
print(f"Type error: {e.display()}")
except pydantic_monty.MontyRuntimeError as e:
print(f"Runtime error: {e.display(format='type-msg')}")
except pydantic_monty.MontyError as e:
print(f"Other Monty error: {e}")
Handle Resource Limit Errors
import pydantic_monty
code = "while True: pass"
m = pydantic_monty.Monty(code)
limits = pydantic_monty.ResourceLimits(max_duration_secs=0.1)
try:
m.run(limits=limits)
except pydantic_monty.MontyRuntimeError as e:
if "resource limit" in str(e).lower():
print("Execution exceeded resource limits")
else:
print(f"Other runtime error: {e}")
import pydantic_monty
code = """
def problematic_function():
x = undefined_variable
problematic_function()
"""
m = pydantic_monty.Monty(code)
try:
m.run()
except pydantic_monty.MontyRuntimeError as e:
# Get the inner Python exception
inner_exc = e.exception()
print(f"Exception type: {type(inner_exc).__name__}")
# Analyze the traceback
frames = e.traceback()
error_location = frames[-1] # Last frame is where error occurred
print(f"Error at {error_location.filename}:{error_location.line}")
print(f"In function: {error_location.function_name}")