CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-hatch

Modern, extensible Python project management tool with comprehensive environment and build system support

Pending
Overview
Eval results
Files

python-management.mddocs/

Python Management

Automated Python distribution management including installation, version management, and distribution discovery. Supports multiple Python versions and provides integration with UV and other Python managers.

Capabilities

Python Manager

Central manager for Python installations providing discovery, installation, and management of multiple Python versions.

class PythonManager:
    """
    Manager for Python installations and distributions.
    
    Handles downloading, installing, and managing multiple Python versions
    with support for different sources and installation methods.
    """
    
    def __init__(self, directory: Path):
        """
        Initialize Python manager.
        
        Args:
            directory (Path): Directory for Python installations
        """
    
    @property
    def directory(self) -> Path:
        """
        Directory containing Python installations.
        
        Returns:
            Path to Python installations directory
        """
    
    def get_installed(self) -> dict[str, 'InstalledDistribution']:
        """
        Get all installed Python distributions.
        
        Returns:
            Dict mapping version strings to InstalledDistribution instances
        """
    
    def install(self, identifier: str) -> 'InstalledDistribution':
        """
        Install Python distribution by version identifier.
        
        Args:
            identifier (str): Version identifier (e.g., '3.11', '3.10.5', 'pypy3.9')
            
        Returns:
            InstalledDistribution instance for the installed Python
            
        Raises:
            PythonDistributionUnknownError: If identifier is not recognized
            PythonDistributionResolutionError: If installation fails
        """
    
    def remove(self, identifier: str) -> None:
        """
        Remove installed Python distribution.
        
        Args:
            identifier (str): Version identifier to remove
        """
    
    def find_distribution(self, identifier: str) -> 'InstalledDistribution | None':
        """
        Find installed distribution by identifier.
        
        Args:
            identifier (str): Version identifier to find
            
        Returns:
            InstalledDistribution if found, None otherwise
        """
    
    def get_available(self) -> list[str]:
        """
        Get list of available Python versions for installation.
        
        Returns:
            List of available version identifiers
        """
    
    def update_all(self) -> list[str]:
        """
        Update all installed Python distributions.
        
        Returns:
            List of updated version identifiers
        """

Installed Distribution

Represents an installed Python distribution with version information and utility methods.

class InstalledDistribution:
    """
    Represents an installed Python distribution.
    
    Provides access to Python executable, version information,
    and utilities for managing the installation.
    """
    
    def __init__(self, path: Path, python_path: Path):
        """
        Initialize installed distribution.
        
        Args:
            path (Path): Installation directory path
            python_path (Path): Path to Python executable
        """
    
    @property
    def path(self) -> Path:
        """
        Installation directory path.
        
        Returns:
            Path to installation directory
        """
    
    @property
    def name(self) -> str:
        """
        Distribution name (e.g., 'cpython', 'pypy').
        
        Returns:
            Distribution name string
        """
    
    @property
    def python_path(self) -> Path:
        """
        Path to Python executable.
        
        Returns:
            Path to python executable
        """
    
    @property
    def version(self) -> str:
        """
        Python version string.
        
        Returns:
            Version string (e.g., '3.11.2')
        """
    
    @property
    def python_version(self) -> tuple[int, int, int]:
        """
        Python version as tuple.
        
        Returns:
            Tuple of (major, minor, patch) version numbers
        """
    
    @property
    def implementation(self) -> str:
        """
        Python implementation name.
        
        Returns:
            Implementation name ('cpython', 'pypy', etc.)
        """
    
    @property
    def architecture(self) -> str:
        """
        Architecture string.
        
        Returns:
            Architecture ('x86_64', 'arm64', etc.)
        """
    
    @property
    def platform(self) -> str:
        """
        Platform string.
        
        Returns:
            Platform ('linux', 'darwin', 'win32', etc.)
        """
    
    def needs_update(self) -> bool:
        """
        Check if distribution needs updating.
        
        Returns:
            True if a newer version is available
        """
    
    def update(self) -> 'InstalledDistribution':
        """
        Update this distribution to latest version.
        
        Returns:
            New InstalledDistribution instance after update
        """
    
    def get_system_info(self) -> dict[str, str]:
        """
        Get detailed system information for this Python.
        
        Returns:
            Dict with system information (version, platform, paths, etc.)
        """
    
    def run_command(self, command: list[str], **kwargs):
        """
        Run command with this Python executable.
        
        Args:
            command (list[str]): Command to run (python will be prepended)
            **kwargs: Additional arguments for subprocess
            
        Returns:
            Command execution result
        """

Python Discovery

Utilities for discovering and validating Python installations on the system including system Python and managed installations.

def discover_system_pythons() -> list[str]:
    """
    Discover Python installations on system PATH.
    
    Returns:
        List of Python executable paths found on system
    """

def validate_python_installation(python_path: Path) -> bool:
    """
    Validate that path points to working Python installation.
    
    Args:
        python_path (Path): Path to Python executable
        
    Returns:
        True if Python installation is valid and working
    """

def get_python_version(python_path: Path) -> str:
    """
    Get version string from Python executable.
    
    Args:
        python_path (Path): Path to Python executable
        
    Returns:
        Version string (e.g., '3.11.2')
        
    Raises:
        PythonDistributionResolutionError: If version cannot be determined
    """

def find_python_by_version(version: str) -> Path | None:
    """
    Find Python executable by version on system.
    
    Args:
        version (str): Version to search for (e.g., '3.11', '3.10.5')
        
    Returns:
        Path to Python executable or None if not found
    """

def get_python_info(python_path: Path) -> dict[str, str]:
    """
    Get detailed information about Python installation.
    
    Args:
        python_path (Path): Path to Python executable
        
    Returns:
        Dict with Python information (version, implementation, platform, etc.)
    """

Version Resolution

Python version parsing, comparison, and resolution utilities for handling different version formats and specifiers.

def parse_version_spec(spec: str) -> dict[str, str]:
    """
    Parse version specification into components.
    
    Args:
        spec (str): Version specification (e.g., '3.11.2', 'pypy3.9', 'python3.10')
        
    Returns:
        Dict with parsed components (implementation, major, minor, patch)
    """

def resolve_version_identifier(identifier: str) -> str:
    """
    Resolve version identifier to specific version.
    
    Args:
        identifier (str): Version identifier to resolve
        
    Returns:
        Resolved specific version string
        
    Raises:
        PythonDistributionUnknownError: If identifier cannot be resolved
    """

def compare_versions(version1: str, version2: str) -> int:
    """
    Compare two Python version strings.
    
    Args:
        version1 (str): First version string
        version2 (str): Second version string
        
    Returns:
        -1 if version1 < version2, 0 if equal, 1 if version1 > version2
    """

def get_latest_version(versions: list[str]) -> str:
    """
    Get latest version from list of version strings.
    
    Args:
        versions (list[str]): List of version strings
        
    Returns:
        Latest version string
    """

def version_matches_spec(version: str, spec: str) -> bool:
    """
    Check if version matches specification.
    
    Args:
        version (str): Version to check
        spec (str): Version specification (supports ranges, ~=, etc.)
        
    Returns:
        True if version matches specification
    """

Installation Sources

Support for different Python installation sources including official releases, PyPy, and custom sources.

class InstallationSource:
    """Base class for Python installation sources."""
    
    def get_available_versions(self) -> list[str]:
        """Get list of available versions from this source."""
    
    def download_distribution(self, version: str, target_dir: Path) -> Path:
        """Download distribution for version to target directory."""
    
    def install_distribution(self, version: str, target_dir: Path) -> InstalledDistribution:
        """Install distribution for version to target directory."""

class OfficialSource(InstallationSource):
    """Official Python.org releases."""
    
    BASE_URL = "https://www.python.org/ftp/python/"
    
    def get_available_versions(self) -> list[str]:
        """Get available CPython versions from python.org."""

class PyPySource(InstallationSource):
    """PyPy releases."""
    
    BASE_URL = "https://downloads.python.org/pypy/"
    
    def get_available_versions(self) -> list[str]:
        """Get available PyPy versions."""

class UVSource(InstallationSource):
    """UV Python installations."""
    
    def get_available_versions(self) -> list[str]:
        """Get Python versions available through UV."""
    
    def install_distribution(self, version: str, target_dir: Path) -> InstalledDistribution:
        """Install Python using UV."""

Python Environment Integration

Integration between Python installations and hatch environments for seamless Python version management.

def get_environment_python(app, env_name: str) -> InstalledDistribution | None:
    """
    Get Python distribution for environment.
    
    Args:
        app: Application instance
        env_name (str): Environment name
        
    Returns:
        Python distribution for environment or None
    """

def set_environment_python(app, env_name: str, python_path: Path) -> None:
    """
    Set Python distribution for environment.
    
    Args:
        app: Application instance
        env_name (str): Environment name
        python_path (Path): Path to Python executable
    """

def ensure_python_for_environment(app, env_config: dict) -> InstalledDistribution:
    """
    Ensure Python is available for environment configuration.
    
    Args:
        app: Application instance
        env_config (dict): Environment configuration
        
    Returns:
        Python distribution for environment
    """

def resolve_python_requirement(requirement: str) -> list[str]:
    """
    Resolve Python requirement to specific versions.
    
    Args:
        requirement (str): Python version requirement (e.g., '>=3.9,<3.12')
        
    Returns:
        List of Python versions that satisfy requirement
    """

Usage Examples

Basic Python Management

from hatch.python.core import PythonManager
from pathlib import Path

# Create Python manager
python_manager = PythonManager(Path.home() / '.hatch' / 'pythons')

# Get installed Python versions
installed = python_manager.get_installed()
print("Installed Python versions:")
for version, distribution in installed.items():
    print(f"  {version}: {distribution.python_path}")

# Install new Python version
if '3.11' not in installed:
    print("Installing Python 3.11...")
    python_311 = python_manager.install('3.11')
    print(f"Installed at: {python_311.python_path}")

# Get available versions
available = python_manager.get_available()
print(f"Available versions: {available[:10]}...")  # Show first 10

Working with Installed Distributions

from hatch.python.core import PythonManager, InstalledDistribution

python_manager = PythonManager(Path.home() / '.hatch' / 'pythons')

# Find specific distribution
python_311 = python_manager.find_distribution('3.11')
if python_311:
    print(f"Python 3.11 found at: {python_311.python_path}")
    print(f"Version: {python_311.version}")
    print(f"Implementation: {python_311.implementation}")
    print(f"Architecture: {python_311.architecture}")
    
    # Check if needs update
    if python_311.needs_update():
        print("Update available")
        updated = python_311.update()
        print(f"Updated to: {updated.version}")
    
    # Get detailed system info
    info = python_311.get_system_info()
    print(f"System info: {info}")
    
    # Run command with this Python
    result = python_311.run_command(['-c', 'import sys; print(sys.version)'])
    print(f"Command output: {result.stdout}")

Python Discovery and Validation

from hatch.python import (
    discover_system_pythons, 
    validate_python_installation,
    get_python_version,
    find_python_by_version
)

# Discover system Pythons
system_pythons = discover_system_pythons()
print("System Python installations:")
for python_path in system_pythons:
    if validate_python_installation(Path(python_path)):
        version = get_python_version(Path(python_path))
        print(f"  {python_path}: {version}")

# Find specific version on system
python_310 = find_python_by_version('3.10')
if python_310:
    print(f"Found Python 3.10 at: {python_310}")
else:
    print("Python 3.10 not found on system")

Version Resolution

from hatch.python import (
    parse_version_spec,
    resolve_version_identifier,
    compare_versions,
    version_matches_spec
)

# Parse version specifications
spec = parse_version_spec('pypy3.9.12')
print(f"Parsed spec: {spec}")

# Resolve version identifier
try:
    resolved = resolve_version_identifier('3.11')
    print(f"Resolved 3.11 to: {resolved}")
except PythonDistributionUnknownError as e:
    print(f"Resolution failed: {e}")

# Compare versions
result = compare_versions('3.11.2', '3.10.8')
print(f"3.11.2 vs 3.10.8: {result}")  # Should be 1 (newer)

# Check version matching
matches = version_matches_spec('3.11.2', '>=3.10,<3.12')
print(f"3.11.2 matches >=3.10,<3.12: {matches}")  # Should be True

Custom Installation Sources

from hatch.python.sources import OfficialSource, PyPySource, UVSource

# Use official Python source
official = OfficialSource()
available_versions = official.get_available_versions()
print(f"Official Python versions: {available_versions[:10]}")

# Install using UV
uv_source = UVSource()
if uv_source.is_available():
    uv_python = uv_source.install_distribution('3.11.8', target_dir)
    print(f"Installed via UV: {uv_python.python_path}")

# Use PyPy source
pypy_source = PyPySource()
pypy_versions = pypy_source.get_available_versions()
print(f"PyPy versions: {pypy_versions}")

Environment Integration

from hatch.cli.application import Application
from hatch.python import get_environment_python, ensure_python_for_environment

app = Application(lambda code: exit(code))

# Get Python for environment
env_python = get_environment_python(app, 'test')
if env_python:
    print(f"Test environment Python: {env_python.version}")

# Ensure Python for environment configuration
env_config = {
    'python': '3.11',
    'dependencies': ['pytest', 'coverage']
}

python_dist = ensure_python_for_environment(app, env_config)
print(f"Ensured Python: {python_dist.version} at {python_dist.python_path}")

# Environment will use this Python
env = app.get_environment('test')
env.create()  # Uses the ensured Python version

Batch Operations

from hatch.python.core import PythonManager

python_manager = PythonManager(Path.home() / '.hatch' / 'pythons')

# Install multiple versions
versions_to_install = ['3.9', '3.10', '3.11', '3.12']
for version in versions_to_install:
    if version not in python_manager.get_installed():
        print(f"Installing Python {version}...")
        try:
            python_manager.install(version)
            print(f"✓ Installed Python {version}")
        except Exception as e:
            print(f"✗ Failed to install Python {version}: {e}")

# Update all installed versions
print("Updating all Python installations...")
updated = python_manager.update_all()
print(f"Updated versions: {updated}")

# Remove old versions
installed = python_manager.get_installed()
for version, distribution in installed.items():
    if distribution.needs_update():
        print(f"Python {version} has updates available")

Install with Tessl CLI

npx tessl i tessl/pypi-hatch

docs

application.md

cli-commands.md

configuration.md

environment-management.md

index.md

plugin-system.md

project-management.md

python-management.md

tile.json