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
¶
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
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:
|
_info
|
Pre-existing Info object for deserialization. If None, capture() will be called to extract code from the with block.
TYPE:
|
**kwargs
|
Additional keyword arguments to pass to the traced function
DEFAULT:
|
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:
|
frame |
Frame information from the call stack where tracing occurred
TYPE:
|
start_line |
Line number where the traced code block begins
TYPE:
|
node |
AST node representing the with block
TYPE:
|
filename |
Filename for the traced code (real file or generated identifier)
TYPE:
|
| PARAMETER | DESCRIPTION |
|---|---|
source
|
List of source code lines from the traced block
TYPE:
|
frame
|
Frame information from the call stack where tracing occurred
TYPE:
|
start_line
|
Line number where the traced code block begins
TYPE:
|
node
|
AST node representing the with block
TYPE:
|
filename
|
Optional filename; generates unique identifier if None
TYPE:
|
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)}>'
copy
¶
Create a deep copy of this Info instance.
| RETURNS | DESCRIPTION |
|---|---|
|
A new Info instance with the same metadata |
__getstate__
¶
Get the state of the info for serialization.
| RETURNS | DESCRIPTION |
|---|---|
|
Dict containing serializable state information |
__setstate__
¶
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 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 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:
|
start_line
|
Line number where the tracer creation statement begins
TYPE:
|
| 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 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 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:
|
push
¶
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:
|
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 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 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) |
__getstate__
¶
Get the state of the tracer for serialization.
| RETURNS | DESCRIPTION |
|---|---|
|
Dict containing the serializable state of the tracer |
__setstate__
¶
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.