tox is a generic virtualenv management and test command line tool
Runtime state coordination and environment selection for tox execution. The session management system controls the overall execution flow, manages environment lifecycle, and provides access to configuration and runtime state throughout the tox run.
The central coordinator that manages the entire tox execution lifecycle, providing access to configuration, environments, and runtime state.
class State:
"""Runtime state holder for tox execution."""
def __init__(self, options: Options, args: Sequence[str]) -> None:
"""
Initialize state for tox run.
Args:
options: Parsed command line options
args: Raw command line arguments
"""
@property
def conf(self) -> Config:
"""Access to configuration object."""
@property
def envs(self) -> EnvSelector:
"""Access to environment selector."""
args: Sequence[str]
"""Raw command line arguments."""Usage example:
from tox.run import setup_state
# Create state
state = setup_state(['-e', 'py311,py312'])
# Access configuration
print(f"Work dir: {state.conf.work_dir}")
print(f"Root dir: {state.conf.root}")
# Access environments
envs = state.envs
for name, env in envs.iter():
print(f"Environment: {name}")Manages the selection and coordination of tox environments, providing access to environment configurations and instances.
class EnvSelector:
"""Environment selection and management."""
@property
def _defined_envs(self) -> dict[str, _ToxEnvInfo]:
"""
Get all defined environments.
Returns:
dict[str, _ToxEnvInfo]: Mapping of environment names to environment info
"""
def iter(self, *, only_active: bool = True, package: bool = False) -> Iterator[str]:
"""
Get tox environments.
Args:
only_active: Active environments marked to be executed
package: Return package environments
Yields:
str: Environment names
"""
def __getitem__(self, item: str) -> RunToxEnv | PackageToxEnv:
"""
Get specific environment by name.
Args:
item: Environment name
Returns:
RunToxEnv | PackageToxEnv: Environment instance
Raises:
KeyError: If environment not found
"""Usage example:
# Get all environments
all_envs = state.envs._defined_envs
print(f"Available environments: {list(all_envs.keys())}")
# Get specific environment
py311_env = state.envs['py311']
print(f"Environment name: {py311_env.name}")
# Iterate over active environments
for name in state.envs.iter():
env = state.envs[name]
print(f"Processing {name}: {env.conf['basepython']}")Tracks execution runs and results for reporting and analysis.
class Journal:
"""Execution journal for tracking tox runs."""
def __init__(self, is_result_json: bool) -> None:
"""
Initialize journal.
Args:
is_result_json: Whether to track for JSON result output
"""
def add_run(self, env_name: str, run_id: str, outcome: Outcome) -> None:
"""
Add execution run to journal.
Args:
env_name: Name of environment
run_id: Unique run identifier
outcome: Execution outcome
"""
def get_runs(self, env_name: str | None = None) -> list[JournalRun]:
"""
Get execution runs.
Args:
env_name: Filter by environment name (None for all)
Returns:
list[JournalRun]: List of execution runs
"""
def write(self, path: Path) -> None:
"""
Write journal to file.
Args:
path: Output file path
"""
class JournalRun:
"""Single execution run record."""
@property
def env_name(self) -> str:
"""Environment name."""
@property
def run_id(self) -> str:
"""Run identifier."""
@property
def outcome(self) -> Outcome:
"""Execution outcome."""Execute environments one after another in sequence.
def run_sequential(state: State) -> int:
"""
Run environments sequentially.
Args:
state: Runtime state
Returns:
int: Exit code (0 for success)
"""Execute multiple environments concurrently.
def run_parallel(state: State) -> int:
"""
Run environments in parallel.
Args:
state: Runtime state
Returns:
int: Exit code (0 for success)
"""Execute a single environment with full lifecycle management.
def execute(state: State, env: ToxEnv) -> int:
"""
Execute single environment.
Args:
state: Runtime state
env: Environment to execute
Returns:
int: Exit code (0 for success)
"""The session management system coordinates the environment lifecycle:
# Example lifecycle coordination
state = setup_state(['-e', 'py311'])
# Get environment
env = state.envs.get('py311')
# Execute with lifecycle management
try:
env.create()
env.setup()
status = env.execute(ExecuteRequest(['pytest']))
print(f"Exit code: {status.exit_code}")
finally:
env.tear_down()Session behavior is controlled through configuration and CLI options:
--parallel: Enable parallel execution--parallel-no-spinner: Disable progress spinner--parallel-live: Show live output during parallel execution-e, --env: Specify environments to run--skip-missing-interpreters: Skip unavailable Python interpreters--develop: Install package in development mode--workdir: Override working directory--temp-dir: Override temporary directorySession management includes comprehensive error handling:
class Skip(Exception):
"""Signal to skip an environment."""
class Fail(Exception):
"""Signal environment failure."""The session system catches and handles these exceptions appropriately:
Skip: Environment is marked as skipped and execution continuesFail: Environment is marked as failed but other environments continueCommon patterns for accessing state information:
# Configuration access
work_dir = state.conf.work_dir
core_config = state.conf.core
env_config = state.conf.get_env('py311')
# Environment access
all_envs = state.envs.all()
active_envs = list(state.envs.iter())
specific_env = state.envs.get('py311')
# Journal access
journal = state.journal
runs = journal.get_runs('py311')This provides a clean separation between configuration, environment management, and execution tracking while maintaining easy access to all necessary state information.
Install with Tessl CLI
npx tessl i tessl/pypi-tox