Skip to content

base

base

Tracing module for capturing and executing code blocks within 'with' statements.

This module provides the core Tracer class that enables dynamic code capture, compilation, and execution. It allows intercepting Python code blocks and executing them in controlled environments with access to the original context.

ExitTracingException

Bases: Exception

Exception raised to exit the tracing process.

This exception is used as a control flow mechanism to cleanly exit a with block without executing the code inside it. When the tracer detects that execution has reached the traced code block, it raises this exception to prevent normal execution and instead execute the code through the tracing backend.

WithBlockNotFoundError

Bases: Exception

Exception raised when a with block is not found in the source code.

This exception indicates that the AST parser could not locate a with block at the expected line number during the code capture process. This typically occurs when there are issues with source code parsing or line number mapping.

Tracer

Tracer(*args, backend: Backend = None, _info: Info = None, **kwargs)

Captures and executes code within a tracing context.

This class provides a sophisticated mechanism for intercepting Python code blocks within 'with' statements, capturing their source code, and executing them in controlled environments. It's designed to enable dynamic code manipulation and execution with full access to the original context and variables.

The tracing process follows four main steps: 1. Capture: Finds and extracts the source code from the with block 2. Parse: Uses AST to identify the exact code boundaries within the block 3. Compile: Wraps the source code in a function definition for execution 4. Execute: Runs the compiled function with appropriate context

Example
with Tracer() as tracer:
    # This code block will be captured and executed later
    x = some_computation()
    result = process(x)

The tracer supports various execution environments including: - Regular Python files - IPython/Jupyter notebooks - Interactive consoles - Nested tracing contexts

ATTRIBUTE DESCRIPTION
args

Arguments passed to the tracer for use during execution

kwargs

Keyword arguments passed to the tracer

backend

Backend implementation that handles the actual code execution

info

Info object containing captured code metadata and context

PARAMETER DESCRIPTION
*args

Additional arguments to pass to the traced function

DEFAULT: ()

backend

Backend implementation for executing the traced code. Defaults to ExecutionBackend if None.

TYPE: Backend DEFAULT: None

_info

Pre-existing Info object for deserialization. If None, capture() will be called to extract code from the with block.

TYPE: Info DEFAULT: None

**kwargs

Additional keyword arguments to pass to the traced function

DEFAULT: {}

args instance-attribute

args = args

kwargs instance-attribute

kwargs = kwargs

backend instance-attribute

backend = ExecutionBackend() if backend is None else backend

info instance-attribute

info = _info if _info is not None else None

asynchronous instance-attribute

asynchronous = False

Info

Info(source: List[str], frame: FrameType, start_line: int, node: With, filename: str = None, cache_key: int = None)

Container for metadata about the traced code block.

This nested class stores all necessary information about the code being traced, including the source code, execution frame context, and AST node information. It serves as a data transfer object between the capture, parse, and execution phases.

ATTRIBUTE DESCRIPTION
source

Source code lines from the traced block

TYPE: List[str]

frame

Frame information from the call stack where tracing occurred

TYPE: FrameType

start_line

Line number where the traced code block begins

TYPE: int

node

AST node representing the with block

TYPE: With

filename

Filename for the traced code (real file or generated identifier)

TYPE: str

PARAMETER DESCRIPTION
source

List of source code lines from the traced block

TYPE: List[str]

frame

Frame information from the call stack where tracing occurred

TYPE: FrameType

start_line

Line number where the traced code block begins

TYPE: int

node

AST node representing the with block

TYPE: With

filename

Optional filename; generates unique identifier if None

TYPE: str DEFAULT: None

source instance-attribute
source = source
frame instance-attribute
frame = frame
start_line instance-attribute
start_line = start_line
node instance-attribute
node = node
filename instance-attribute
filename = filename if filename is not None else f'<nnsight {abs(cache_key) if cache_key is not None else id(self)}>'
cache_key instance-attribute
cache_key = cache_key
copy
copy()

Create a deep copy of this Info instance.

RETURNS DESCRIPTION

A new Info instance with the same metadata

__getstate__
__getstate__()

Get the state of the info for serialization.

RETURNS DESCRIPTION

Dict containing serializable state information

__setstate__
__setstate__(state)

Restore the state of the info from serialization.

PARAMETER DESCRIPTION
state

Dictionary containing the serialized state

Note

AST node is set to None as it cannot be serialized

capture

capture()

Capture the code block within the 'with' statement.

This is step 1 of the tracing process. It walks up the call stack to find the frame outside of nnsight, extracts the source code of the 'with' block, and prepares it for later execution. The method handles various execution environments including regular files, IPython notebooks, and interactive consoles.

The capture process: 1. Identifies the execution context (file, notebook, console, nested trace) 2. Extracts source code lines from the appropriate source 3. Handles indentation normalization for proper AST parsing 4. Calls parse() to identify the exact with block boundaries 5. Stores all metadata in a Tracer.Info object

RAISES DESCRIPTION
ValueError

If no source code can be found for the current context

parse

parse(source_lines: List[str], start_line: int)

Parse the source code to extract the with block contents.

This is step 2 of the tracing process. Uses the Abstract Syntax Tree (AST) to identify the exact boundaries of the with block and extract only the code that should be traced and executed later.

PARAMETER DESCRIPTION
source_lines

List of source code lines to parse

TYPE: List[str]

start_line

Line number where the tracer creation statement begins

TYPE: int

RETURNS DESCRIPTION

Tuple containing: - start_line (int): Adjusted start line of the with block body - source_lines (List[str]): Extracted source lines from the with block - node (ast.With): AST node representing the with block

RAISES DESCRIPTION
WithBlockNotFoundError

If no with block is found at the specified line

compile

compile() -> Callable

Compile the captured source code into a callable function.

This is step 3 of the tracing process. Takes the captured and parsed source code and wraps it in a function definition with the necessary context parameters. The resulting function can be executed with proper variable scoping and access to the original execution environment.

The compiled function signature is: __nnsight_tracer_{id}__(__nnsight_tracer__, __nnsight_tracing_info__)

The function includes: - A call to tracer.pull() to import variables from the original scope - The original traced code block - A call to tracer.push() to export variables back to the original scope

RETURNS DESCRIPTION
Callable

A callable function that executes the captured code block with proper context

execute

execute(fn: Callable)

Execute the compiled function with proper context.

This is step 4 of the tracing process. Runs the compiled function that was created in the compile() step, passing in the tracer instance and info object as context. This allows the traced code to access the original variables and execution environment.

PARAMETER DESCRIPTION
fn

The compiled function to execute (created by compile() method)

TYPE: Callable

push

push(state: Dict = None)

Push local variables back to the original execution frame.

This method exports variables from the traced code execution back to the original scope where the tracer was created. This allows changes made during tracing to persist and affect the original execution environment.

The method handles variable filtering to only push non-nnsight variables, and includes special logic for nested tracing contexts using Globals.stack.

PARAMETER DESCRIPTION
state

Dictionary of variable names and values to push to the frame. If None, automatically collects variables from the current execution frame.

TYPE: Dict DEFAULT: None

pull

pull()

Pull variables from the original execution frame into the current context.

This method imports variables from the original scope where the tracer was created into the current traced code execution context. This ensures that the traced code has access to all variables that were available when the tracer was instantiated.

This is the opposite operation of push() and is called at the beginning of traced code execution.

__enter__

__enter__()

Enter the tracing context.

This method is called when entering the 'with' statement. It sets up the tracing mechanism that will capture the code block and prevent its normal execution. Instead, the code will be executed later through the backend.

The method: 1. Captures the code block if not already done 2. Checks for empty code blocks (just 'pass' statements) 3. Sets up a trace function that raises ExitTracingException when the traced code is reached, preventing normal execution

RETURNS DESCRIPTION

The Tracer instance for use in the 'with' statement

__exit__

__exit__(exc_type, exc_val, exc_tb)

Exit the tracing context and execute the captured code.

This method is called when exiting the 'with' statement. It handles the execution of the captured code through the configured backend, and manages exception handling for the tracing mechanism.

PARAMETER DESCRIPTION
exc_type

Exception type if an exception was raised in the with block

exc_val

Exception value if an exception was raised

exc_tb

Exception traceback if an exception was raised

RETURNS DESCRIPTION

True if an ExitTracingException was caught (suppresses the exception),

None otherwise (allows other exceptions to propagate)

__aenter__ async

__aenter__()

__aexit__ async

__aexit__(exc_type, exc_val, exc_tb)

__getstate__

__getstate__()

Get the state of the tracer for serialization.

RETURNS DESCRIPTION

Dict containing the serializable state of the tracer

__setstate__

__setstate__(state)

Restore the state of the tracer from serialization.

PARAMETER DESCRIPTION
state

Dictionary containing the serialized tracer state

Note

The backend is reset to ExecutionBackend and start_line is reset to 0 since these cannot be reliably serialized across different contexts.