CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-hatchling

Modern, extensible Python build backend implementing PEP 517/660 standards with plugin architecture.

Pending
Overview
Eval results
Files

version.mddocs/

Version Management

Pluggable version sources and schemes for flexible version handling across different project structures and workflows. The version system enables dynamic version resolution and manipulation through configurable plugins.

Capabilities

Version Source Interface

Abstract interface for version source plugins that determine project versions from various sources.

class VersionSourceInterface(ABC):
    def get_version_data(self) -> dict:
        """
        Get the current version data.
        
        Returns:
            dict: Dictionary with 'version' key and current version string
            
        Raises:
            RuntimeError: If version cannot be determined
        """
    
    def set_version(self, version: str, version_data: dict) -> None:
        """
        Set the version with data from get_version_data.
        
        Args:
            version: Version string to set
            version_data: Data dictionary from get_version_data
            
        Raises:
            RuntimeError: If version cannot be set
            NotImplementedError: If version setting is not supported
        """

Version Scheme Interface

Abstract interface for version scheme plugins that manipulate and validate version strings.

class VersionSchemeInterface(ABC):
    def update(self, version: str, **kwargs) -> str:
        """
        Update a version string according to scheme rules.
        
        Args:
            version: Version string to update
            **kwargs: Additional update parameters (e.g., part="patch")
            
        Returns:
            str: Updated version string
        """
    
    def parse(self, version: str) -> dict:
        """
        Parse a version string into components.
        
        Args:
            version: Version string to parse
            
        Returns:
            dict: Version components (e.g., {"major": 1, "minor": 2, "patch": 3})
        """
    
    def normalize(self, version: str) -> str:
        """
        Normalize a version string according to scheme rules.
        
        Args:
            version: Version string to normalize
            
        Returns:
            str: Normalized version string
        """

Built-in Version Sources

Code Source

Extracts version from Python code using AST parsing.

class CodeSource(VersionSourceInterface):
    """
    Extract version from Python code files.
    
    Configuration:
        path: Path to Python file containing version
        pattern: Regex pattern to find version (optional)
        search-paths: Additional paths to search (optional)
    """

Configuration example:

[tool.hatch.version]
source = "code"
path = "src/package/__about__.py"

Regex Source

Extracts version using regular expression patterns on files.

class RegexSource(VersionSourceInterface):
    """
    Extract version using regex patterns.
    
    Configuration:
        path: Path to file containing version
        pattern: Regex pattern with named group 'version'
    """

Configuration example:

[tool.hatch.version]
source = "regex"
path = "VERSION.txt"
pattern = 'version = "(?P<version>[^"]+)"'

Environment Variable Source

Gets version from environment variables.

class EnvSource(VersionSourceInterface):
    """
    Get version from environment variables.
    
    Configuration:
        variable: Environment variable name
    """

Configuration example:

[tool.hatch.version]
source = "env"
variable = "PACKAGE_VERSION"

Built-in Version Schemes

Standard Scheme

Standard PEP 440 compliant version scheme with semantic versioning support.

class StandardScheme(VersionSchemeInterface):
    """
    Standard PEP 440 compliant version scheme.
    
    Supports:
        - Semantic versioning (MAJOR.MINOR.PATCH)
        - Pre-release versions (alpha, beta, rc)
        - Post-release versions
        - Development versions
        - Local versions
    """

Configuration example:

[tool.hatch.version]
scheme = "standard"

Version File Management

Version File Handling

class VersionFile:
    def __init__(self, path: str, search_paths: list[str] | None = None):
        """
        Initialize version file handler.
        
        Args:
            path: Path to version file
            search_paths: Additional search paths
        """
    
    def read(self) -> str:
        """
        Read version from file.
        
        Returns:
            str: Version string
        """
    
    def write(self, version: str) -> None:
        """
        Write version to file.
        
        Args:
            version: Version string to write
        """

Configuration Examples

Code Source Configuration

Extract version from Python file:

[tool.hatch.version]
source = "code"
path = "src/mypackage/__about__.py"

Python file content:

# src/mypackage/__about__.py
__version__ = "1.2.3"

Regex Source Configuration

Extract version from any text file:

[tool.hatch.version]
source = "regex"
path = "VERSION"
pattern = '(?P<version>\d+\.\d+\.\d+)'

File content:

Version: 1.2.3

Environment Variable Configuration

Get version from environment:

[tool.hatch.version]
source = "env"
variable = "PACKAGE_VERSION"

Custom Pattern Configuration

Use custom regex pattern:

[tool.hatch.version]
source = "regex"
path = "Cargo.toml"
pattern = 'version = "(?P<version>[^"]+)"'

Version Manipulation

Dynamic Version Updates

from hatchling.version.core import VersionFile

# Read current version
version_file = VersionFile("src/package/__about__.py")
current_version = version_file.read()
print(f"Current version: {current_version}")

# Update version
version_file.write("1.3.0")

Scheme-based Version Updates

from hatchling.version.scheme.standard import StandardScheme

scheme = StandardScheme()

# Parse version components
components = scheme.parse("1.2.3")
print(components)  # {"major": 1, "minor": 2, "patch": 3}

# Update version
new_version = scheme.update("1.2.3", part="minor")
print(new_version)  # "1.3.0"

# Normalize version
normalized = scheme.normalize("01.02.03")
print(normalized)  # "1.2.3"

CLI Integration

Version Commands

Check current version:

hatchling version

Set new version:

hatchling version 2.0.0

Preview version change:

hatchling version 2.0.0 --dry-run

Custom Version Sources

Creating Custom Version Source

from hatchling.version.source.plugin.interface import VersionSourceInterface

class GitTagSource(VersionSourceInterface):
    PLUGIN_NAME = "git-tag"
    
    def get_version(self):
        import subprocess
        result = subprocess.run(
            ["git", "describe", "--tags", "--abbrev=0"],
            capture_output=True, text=True
        )
        if result.returncode == 0:
            return result.stdout.strip().lstrip('v')
        raise RuntimeError("No git tags found")
    
    def set_version(self, version):
        import subprocess
        subprocess.run(["git", "tag", f"v{version}"], check=True)

Register the plugin:

[project.entry-points.hatch_version_source]
git-tag = "mypackage.version:GitTagSource"

Use the custom source:

[tool.hatch.version]
source = "git-tag"

Custom Version Schemes

Creating Custom Version Scheme

from hatchling.version.scheme.plugin.interface import VersionSchemeInterface
import re

class CalendarScheme(VersionSchemeInterface):
    PLUGIN_NAME = "calendar"
    
    def update(self, version, **kwargs):
        from datetime import datetime
        return datetime.now().strftime("%Y.%m.%d")
    
    def parse(self, version):
        match = re.match(r'(\d{4})\.(\d{2})\.(\d{2})', version)
        if match:
            return {
                "year": int(match.group(1)),
                "month": int(match.group(2)), 
                "day": int(match.group(3))
            }
        return {}
    
    def normalize(self, version):
        components = self.parse(version)
        if components:
            return f"{components['year']}.{components['month']:02d}.{components['day']:02d}"
        return version

Error Handling

Common version-related exceptions:

  • FileNotFoundError: Version file not found
  • ValueError: Invalid version format
  • RuntimeError: Version source/scheme operation failed
  • NotImplementedError: Unsupported operation

Best Practices

Version Source Selection

  • Code source: Best for Python packages with __version__ attributes
  • Regex source: Flexible for any text-based version storage
  • Environment source: Useful for CI/CD and containerized deployments

Version Scheme Guidelines

  • Use standard scheme for PEP 440 compliance
  • Implement custom schemes for specialized versioning needs
  • Always validate version strings before operations

Configuration Recommendations

# Recommended for Python packages
[tool.hatch.version]
source = "code"
path = "src/package/__about__.py"
scheme = "standard"

# Recommended for multi-language projects
[tool.hatch.version]
source = "regex"
path = "VERSION"
pattern = '(?P<version>\d+\.\d+\.\d+)'
scheme = "standard"

The version management system provides flexible, pluggable version handling that adapts to different project structures and workflows while maintaining PEP 440 compliance.

Install with Tessl CLI

npx tessl i tessl/pypi-hatchling

docs

build-backend.md

builders.md

cli.md

index.md

metadata.md

plugins.md

version.md

tile.json