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

plugins.mddocs/

Plugin System

Extensible plugin architecture supporting custom builders, build hooks, version sources, version schemes, and metadata hooks. The plugin system enables third-party extensions and customization of hatchling's functionality.

Capabilities

Plugin Manager

Central plugin management system that discovers, loads, and manages all plugin types.

class PluginManager:
    def __init__(self):
        """
        Initialize plugin manager.
        
        Note:
            The PluginManager uses dynamic initialization and does not
            require parameters during construction.
        """
    
    @property
    def builders(self) -> dict[str, type[BuilderInterface]]:
        """Dictionary of available builder plugins."""
    
    @property
    def build_hooks(self) -> dict[str, type[BuildHookInterface]]:
        """Dictionary of available build hook plugins."""
    
    @property
    def version_sources(self) -> dict[str, type[VersionSourceInterface]]:
        """Dictionary of available version source plugins."""
    
    @property
    def version_schemes(self) -> dict[str, type[VersionSchemeInterface]]:
        """Dictionary of available version scheme plugins."""
    
    @property
    def metadata_hooks(self) -> dict[str, type[MetadataHookInterface]]:
        """Dictionary of available metadata hook plugins."""

Builder Interface

Abstract base class for all builder plugins.

class BuilderInterface(ABC, Generic[BuilderConfigBound, PluginManagerBound]):
    def build(
        self, *, 
        directory: str | None = None, 
        versions: list[str] | None = None,
        hooks_only: bool | None = None,
        clean: bool | None = None,
        clean_hooks_after: bool | None = None,
        clean_only: bool | None = False
    ) -> Generator[str, None, None]:
        """
        Build distributions and yield paths to built files.
        
        Args:
            directory: Output directory for built distributions (default: "dist")
            versions: List of version types to build
            hooks_only: Whether to run only build hooks
            clean: Whether to clean build directory before building
            clean_hooks_after: Whether to clean hooks after building
            clean_only: Whether to only clean without building
            
        Yields:
            str: Paths to built distribution files
        """
    
    def get_version_api(self) -> dict[str, Callable]:
        """
        Get version API information for this builder.
        
        Returns:
            dict: Version API information
        """
    
    def iter_build_targets(self, versions: list[str]) -> Iterator[tuple[str, str]]:
        """
        Iterate over build targets for given versions.
        
        Args:
            versions: List of version types
            
        Yields:
            tuple[str, str]: (version, target_name) pairs
        """

Build Hook Interface

Abstract base class for build hooks that customize the build process.

class BuildHookInterface(Generic[BuilderConfigBound]):
    def clean(self, versions: list[str]) -> None:
        """
        Clean up build artifacts for specified versions.
        
        Args:
            versions: List of version types to clean
        """
    
    def initialize(self, version: str, build_data: dict[str, Any]) -> None:
        """
        Initialize hook before building.
        
        Args:
            version: Version being built
            build_data: Build data dictionary
        """
    
    def finalize(self, version: str, build_data: dict[str, Any], artifact_path: str) -> None:
        """
        Finalize hook after building.
        
        Args:
            version: Version that was built
            build_data: Build data dictionary
            artifact_path: Path to built artifact
        """

Version Source Interface

Abstract base class for version source plugins that determine project versions.

class VersionSourceInterface(ABC):
    def get_version_data(self) -> dict:
        """
        Get the current version data.
        
        Returns:
            dict: Dictionary with 'version' key and current version string
        """
    
    def set_version(self, version: str, version_data: dict) -> None:
        """
        Set the version.
        
        Args:
            version: Version string to set
        """

Version Scheme Interface

Abstract base class for version scheme plugins that manipulate version strings.

class VersionSchemeInterface(ABC):
    def update(self, version: str, **kwargs) -> str:
        """
        Update a version string.
        
        Args:
            version: Version string to update
            **kwargs: Additional update parameters
            
        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
        """
    
    def normalize(self, version: str) -> str:
        """
        Normalize a version string.
        
        Args:
            version: Version string to normalize
            
        Returns:
            str: Normalized version string
        """

Metadata Hook Interface

Abstract base class for metadata hook plugins that modify project metadata.

class MetadataHookInterface(ABC):
    def update(self, metadata: dict[str, Any]) -> None:
        """
        Update project metadata.
        
        Args:
            metadata: Metadata dictionary to modify
        """

Built-in Plugin Implementations

Version Sources

Built-in version source implementations for common version management patterns.

class CodeSource(VersionSourceInterface):
    """Extract version from Python code using AST parsing."""

class RegexSource(VersionSourceInterface):
    """Extract version using regular expression patterns."""

class EnvSource(VersionSourceInterface):
    """Get version from environment variables."""

Version Schemes

class StandardScheme(VersionSchemeInterface):
    """Standard PEP 440 compliant version scheme."""

Build Hooks

class VersionBuildHook(BuildHookInterface):
    """Hook for managing version information during builds."""

class CustomBuildHook:
    """Custom user-defined build hook loaded from scripts."""

Metadata Hooks

class CustomMetadataHook:
    """Custom user-defined metadata hook loaded from scripts."""

Plugin Registration

Registration Functions

Functions for registering built-in plugins.

def hatch_register_builder() -> list[type[BuilderInterface]]:
    """Register built-in builder plugins."""

def hatch_register_build_hook() -> list[type[BuildHookInterface]]:
    """Register built-in build hook plugins."""

Plugin Entry Points

Plugins are discovered through entry points in setup.py or pyproject.toml:

[project.entry-points.hatch_builder]
my_builder = "my_package.builders:MyBuilder"

[project.entry-points.hatch_build_hook]
my_hook = "my_package.hooks:MyBuildHook"

[project.entry-points.hatch_version_source]
my_source = "my_package.version:MyVersionSource"

[project.entry-points.hatch_version_scheme]
my_scheme = "my_package.version:MyVersionScheme"

[project.entry-points.hatch_metadata_hook]
my_metadata = "my_package.metadata:MyMetadataHook"

Plugin Development

Creating Custom Builders

from hatchling.builders.plugin.interface import BuilderInterface

class MyBuilder(BuilderInterface):
    PLUGIN_NAME = "my-builder"
    
    def build(self, *, directory="dist", versions=None):
        # Custom build logic
        yield self.create_my_distribution(directory)
    
    def get_version_api(self):
        return {"my-version": "1.0"}

Creating Build Hooks

from hatchling.builders.hooks.plugin.interface import BuildHookInterface

class MyBuildHook(BuildHookInterface):
    PLUGIN_NAME = "my-hook"
    
    def initialize(self, version, build_data):
        # Pre-build customization
        build_data["custom_setting"] = "value"
    
    def finalize(self, version, build_data, artifact_path):
        # Post-build customization
        print(f"Built {artifact_path}")

Creating Version Sources

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

class MyVersionSource(VersionSourceInterface):
    PLUGIN_NAME = "my-source"
    
    def get_version_data(self):
        # Custom version retrieval logic
        return {"version": "1.0.0"}
    
    def set_version(self, version, version_data):
        # Custom version setting logic
        pass

Plugin Configuration

Plugins are configured in pyproject.toml:

[tool.hatch.build]
builder = "my-builder"
hooks = ["my-hook"]

[tool.hatch.version]
source = "my-source"
scheme = "my-scheme"

[tool.hatch.metadata.hooks.my-metadata]
setting = "value"

Plugin Utilities

Plugin Loading

def load_plugin_from_script(
    path: str,
    script_name: str,
    plugin_class: type[T],
    plugin_id: str
) -> type[T]:
    """
    Load a plugin class from a Python script.
    
    Args:
        path: Path to script file  
        script_name: Name of the script
        plugin_class: Expected plugin base class
        plugin_id: Plugin identifier
        
    Returns:
        type[T]: Loaded plugin class
    """

Plugin Management Classes

class ClassRegister:
    """Registry for plugin classes with validation."""

class ThirdPartyPlugins:
    """Manager for third-party plugin discovery and loading."""

Error Handling

class UnknownPluginError(ValueError):
    """Raised when referencing an unknown plugin."""

Usage Examples

Using Plugin Manager

from hatchling.metadata.core import ProjectMetadata
from hatchling.plugin.manager import PluginManager

# Create plugin manager
plugin_manager = PluginManager()

# List available plugins
print("Builders:", list(plugin_manager.builders.keys()))
print("Build hooks:", list(plugin_manager.build_hooks.keys()))
print("Version sources:", list(plugin_manager.version_sources.keys()))
print("Version schemes:", list(plugin_manager.version_schemes.keys()))
print("Metadata hooks:", list(plugin_manager.metadata_hooks.keys()))

# Get specific plugin
wheel_builder = plugin_manager.builders["wheel"]
standard_scheme = plugin_manager.version_schemes["standard"]

Using Plugins in Configuration

# Configure builder with plugins
from hatchling.builders.wheel import WheelBuilder

builder = WheelBuilder(
    root=os.getcwd(),
    plugin_manager=plugin_manager,
    config={
        "hooks": ["version", "my-custom-hook"],
        "version-source": "code",
        "version-scheme": "standard"
    }
)

Plugin Registration

Third-party plugins can be registered using hatchling's plugin system.

from hatchling.plugin import hookimpl

@hookimpl
def hatch_register_builder():
    """Register a custom builder plugin."""
    return MyBuilderClass

@hookimpl  
def hatch_register_version_source():
    """Register a custom version source plugin."""
    return MyVersionSourceClass

@hookimpl
def hatch_register_version_scheme():
    """Register a custom version scheme plugin."""
    return MyVersionSchemeClass

@hookimpl
def hatch_register_metadata_hook():
    """Register a custom metadata hook plugin."""
    return MyMetadataHookClass

@hookimpl
def hatch_register_build_hook():
    """Register a custom build hook plugin."""
    return MyBuildHookClass

Usage Example

# plugin.py
from hatchling.plugin import hookimpl
from hatchling.builders.plugin.interface import BuilderInterface

class CustomBuilder(BuilderInterface):
    PLUGIN_NAME = 'custom'
    
    def get_version_api(self):
        return {'standard': self.build_standard}
    
    def build_standard(self, directory, **build_data):
        # Custom build logic
        pass

@hookimpl
def hatch_register_builder():
    return CustomBuilder

The plugin system makes hatchling highly extensible, allowing custom build logic, version management, and metadata processing to be implemented as reusable plugins.

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