CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-tox

tox is a generic virtualenv management and test command line tool

Overview
Eval results
Files

environment-system.mddocs/

Environment System

Virtual environment creation, management, and lifecycle control for tox. The environment system supports different environment types including Python virtual environments, external environments, and custom environment implementations through a flexible hierarchy and plugin system.

Capabilities

Base Environment Class

The foundational environment abstraction that defines the interface for all tox environments.

class ToxEnv:
    """Base tox environment class."""
    
    def __init__(self, create_args: ToxEnvCreateArgs) -> None:
        """
        Initialize the tox environment.
        
        Args:
            create_args: Environment creation arguments
        """
    
    def setup(self) -> None:
        """
        Setup the environment for use.
        
        This installs dependencies, configures the environment,
        and prepares it for command execution.
        """
    
    def teardown(self) -> None:
        """
        Clean up the environment.
        
        This removes temporary files and releases resources
        used by the environment.
        """
    
    def execute(self, cmd: Sequence[Path | str], stdin: StdinSource, 
                show: bool | None = None, cwd: Path | None = None,
                run_id: str = "", executor: Execute | None = None) -> Outcome:
        """
        Execute commands in the environment.
        
        Args:
            cmd: Command and arguments to execute
            stdin: Standard input source
            show: Whether to show output
            cwd: Working directory for execution
            run_id: Unique identifier for this execution
            executor: Custom executor to use
            
        Returns:
            Outcome: Execution result with exit code and output
        """
    
    @property
    def name(self) -> str:
        """Environment name (e.g., 'py311', 'docs')."""
        
    @property
    def conf(self) -> EnvConfigSet:
        """Environment configuration."""
        
    @property
    def core(self) -> CoreConfigSet:
        """Core tox configuration."""
        
    @property
    def env_dir(self) -> Path:
        """The tox environment directory."""
        
    @property
    def cache(self) -> Info:
        """Environment cache/info management."""
        
    def register_config(self) -> None:
        """Register configuration options for this environment."""
        
    @staticmethod
    @abstractmethod
    def id() -> str:
        """Return the type ID of this environment."""
        
    @property
    @abstractmethod 
    def executor(self) -> Execute:
        """Return the executor for this environment."""
        
    @property
    @abstractmethod
    def installer(self) -> Installer[Any]:
        """Return the installer for this environment."""
        
    @property
    @abstractmethod
    def runs_on_platform(self) -> str:
        """Return platform regex this environment runs on."""

Python Environments

Specialized environment classes for Python-based testing and execution.

class PythonToxEnv(ToxEnv):
    """Python-specific tox environment."""
    
    def python_executable(self) -> Path:
        """
        Get path to Python executable for this environment.
        
        Returns:
            Path: Path to Python interpreter
        """
    
    def install_deps(self) -> None:
        """Install environment dependencies."""
    
    def install_package(self, package_path: Path) -> None:
        """
        Install package in environment.
        
        Args:
            package_path: Path to package to install
        """
    
    @property
    def base_python(self) -> str:
        """Base Python version specification."""

class VirtualEnvToxEnv(PythonToxEnv):
    """Virtual environment implementation for Python."""
    
    def create_virtual_env(self) -> None:
        """Create the virtual environment."""
        
    @property
    def virtual_env_path(self) -> Path:
        """Path to virtual environment directory."""

class VirtualEnvRunner:
    """Runner for virtual environment operations."""
    
    def create(self, base_python: str, path: Path) -> None:
        """
        Create virtual environment.
        
        Args:
            base_python: Base Python interpreter
            path: Target path for virtual environment
        """

Environment Types

Different categories of environments supported by tox.

class RunToxEnv(ToxEnv):
    """Environment for running commands."""
    
    def run_commands(self, commands: list[str]) -> ExecuteStatus:
        """
        Run sequence of commands.
        
        Args:
            commands: Commands to execute
            
        Returns:
            ExecuteStatus: Combined execution status
        """

class PackageToxEnv(ToxEnv):
    """Environment for packaging operations."""
    
    def build_package(self) -> Path:
        """
        Build package in this environment.
        
        Returns:
            Path: Path to built package
        """

Environment Registry

System for registering and discovering environment types.

class ToxEnvInfo:
    """Information about an environment type."""
    
    def __init__(self, name: str, description: str, factory: type) -> None:
        """
        Initialize environment info.
        
        Args:
            name: Environment type name
            description: Human-readable description
            factory: Environment class factory
        """
    
    @property
    def name(self) -> str:
        """Environment type name."""
        
    @property
    def description(self) -> str:
        """Environment description."""

# Global environment registry
REGISTER: dict[str, ToxEnvInfo]

Package Management

System for managing package installation and dependencies within environments.

class PipInstall:
    """Pip installation handler for Python environments."""
    
    def __init__(self, env: PythonToxEnv) -> None:
        """
        Initialize pip installer.
        
        Args:
            env: Python environment
        """
    
    def install(self, packages: list[str]) -> ExecuteStatus:
        """
        Install packages via pip.
        
        Args:
            packages: Package specifications to install
            
        Returns:
            ExecuteStatus: Installation result
        """
    
    def install_requirements(self, req_file: Path) -> ExecuteStatus:
        """
        Install from requirements file.
        
        Args:
            req_file: Path to requirements file
            
        Returns:
            ExecuteStatus: Installation result
        """

class RequirementsFile:
    """Handler for requirements files."""
    
    def __init__(self, path: Path) -> None:
        """
        Initialize requirements file handler.
        
        Args:
            path: Path to requirements file
        """
    
    def read(self) -> list[str]:
        """
        Read requirements from file.
        
        Returns:
            list[str]: List of requirement specifications
        """

Environment Configuration

Core Environment Settings

Key configuration options that control environment behavior:

# Example environment configuration
[testenv:py311]
basepython = python3.11
deps = 
    pytest>=6.0
    pytest-cov>=2.0
    requests
commands = 
    pytest {posargs}
    coverage report
changedir = {toxinidir}/tests
passenv = 
    HOME
    USER
    CI
setenv =
    PYTHONPATH = {toxinidir}/src
    COVERAGE_FILE = {envtmpdir}/.coverage

Environment Variables

Control environment behavior through variables:

  • basepython: Python interpreter to use
  • deps: Dependencies to install
  • commands: Commands to execute
  • commands_pre: Pre-execution commands
  • commands_post: Post-execution commands
  • changedir: Working directory
  • passenv: Environment variables to inherit
  • setenv: Environment variables to set
  • install_command: Custom install command
  • allowlist_externals: Allowed external commands

Environment Lifecycle Hooks

Control points in the environment lifecycle:

# Pre/post command hooks
[testenv]
commands_pre = 
    python --version
    pip list
commands = pytest {posargs}  
commands_post =
    coverage html
    echo "Tests completed"

Custom Environment Types

Create custom environment types by extending the base classes:

from tox.tox_env.api import ToxEnv
from tox.plugin import impl

class CustomToxEnv(ToxEnv):
    """Custom environment implementation."""
    
    def create(self) -> None:
        """Custom environment creation."""
        print(f"Creating custom environment: {self.name}")
        
    def setup(self) -> None:
        """Custom environment setup.""" 
        print(f"Setting up custom environment: {self.name}")
        
    def execute(self, request):
        """Custom command execution."""
        print(f"Executing in {self.name}: {request.cmd}")
        # Custom execution logic
        return ExecuteStatus(0, "", "")

@impl
def tox_register_tox_env(register):
    """Register custom environment type."""
    register.add_env_type(
        name="custom",
        factory=CustomToxEnv,
        description="Custom environment type"
    )

Environment Selection

Environments can be selected through various mechanisms:

Command Line Selection

# Run specific environments
tox -e py311,py312

# Run all environments
tox

# Run environments matching pattern
tox -e py3{11,12}

Configuration-Based Selection

[tox]
envlist = py311,py312,docs,lint

# Conditional environments
[testenv:docs]
deps = sphinx
commands = sphinx-build docs docs/_build

[testenv:lint] 
deps = flake8
commands = flake8 src/

Programmatic Selection

from tox.session.state import State

# Select specific environments
state = setup_state(['-e', 'py311,docs'])

# Get selected environments
selected = state.envs.all()
for name, env in selected.items():
    print(f"Selected: {name}")

Error Handling

Environment system includes specific error handling:

class ToxEnvError(Exception):
    """Base environment error."""

class SkipEnvironment(Exception):
    """Skip this environment."""

class FailEnvironment(Exception):
    """Mark environment as failed."""

Usage in custom environments:

def setup(self) -> None:
    if not self.python_executable().exists():
        raise SkipEnvironment(f"Python not found: {self.base_python}")
        
    try:
        self.install_deps()
    except Exception as e:
        raise FailEnvironment(f"Dependency installation failed: {e}")

Environment Isolation

Tox provides strong isolation between environments:

  • File System: Each environment has separate directories
  • Python Path: Isolated Python installations and packages
  • Environment Variables: Controlled variable inheritance
  • Process Isolation: Commands run in separate processes
  • Resource Management: Separate resource allocation per environment

This isolation ensures that environments don't interfere with each other and provides reproducible testing conditions.

Install with Tessl CLI

npx tessl i tessl/pypi-tox

docs

cli-interface.md

configuration.md

environment-system.md

execution-system.md

index.md

plugin-system.md

session-management.md

tile.json