Modern, extensible Python build backend implementing PEP 517/660 standards with plugin architecture.
—
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.
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
"""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
"""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"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>[^"]+)"'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"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"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
"""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"Extract version from any text file:
[tool.hatch.version]
source = "regex"
path = "VERSION"
pattern = '(?P<version>\d+\.\d+\.\d+)'File content:
Version: 1.2.3Get version from environment:
[tool.hatch.version]
source = "env"
variable = "PACKAGE_VERSION"Use custom regex pattern:
[tool.hatch.version]
source = "regex"
path = "Cargo.toml"
pattern = 'version = "(?P<version>[^"]+)"'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")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"Check current version:
hatchling versionSet new version:
hatchling version 2.0.0Preview version change:
hatchling version 2.0.0 --dry-runfrom 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"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 versionCommon version-related exceptions:
FileNotFoundError: Version file not foundValueError: Invalid version formatRuntimeError: Version source/scheme operation failedNotImplementedError: Unsupported operation__version__ attributes# 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