CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-setuptools-scm

The blessed package to manage your versions by SCM tags

Pending
Overview
Eval results
Files

version-schemes.mddocs/

Version and Local Schemes

setuptools-scm uses configurable schemes to transform SCM metadata into version strings. Version schemes determine the main version format, while local schemes control the local version identifier (the part after +).

Capabilities

Version Schemes

Functions that determine how the main version string is calculated from SCM metadata.

def guess_next_dev_version(version: ScmVersion) -> str:
    """
    Default version scheme. Returns exact tag for clean repos, 
    or guessed next version with .dev suffix for repos with commits after tag.
    
    Examples:
    - Exact tag "1.0.0" → "1.0.0"  
    - Tag "1.0.0" + 3 commits → "1.0.1.dev3"
    """

def no_guess_dev_version(version: ScmVersion) -> str:
    """
    Returns exact tag for clean repos, tag with .dev suffix for dirty repos.
    Does not attempt to guess next version.
    
    Examples:
    - Exact tag "1.0.0" → "1.0.0"
    - Tag "1.0.0" + 3 commits → "1.0.0.dev3"
    """

def only_version(version: ScmVersion) -> str:
    """
    Always returns the exact tag version, ignoring distance and dirty state.
    
    Examples:
    - Tag "1.0.0" (any state) → "1.0.0"
    """

def postrelease_version(version: ScmVersion) -> str:
    """
    Uses post-release versioning scheme with .post suffix.
    
    Examples:
    - Exact tag "1.0.0" → "1.0.0"
    - Tag "1.0.0" + 3 commits → "1.0.0.post3"
    """

def simplified_semver_version(version: ScmVersion) -> str:
    """
    Simplified semantic versioning that bumps appropriate version component.
    
    Examples:
    - Exact tag "1.0.0" → "1.0.0"
    - Tag "1.0.0" + commits → "1.0.1.dev{distance}"
    - Feature branch → "1.1.0.dev{distance}"
    """

def release_branch_semver_version(version: ScmVersion) -> str:
    """
    Semantic versioning with release branch support.
    Different bumping strategy based on branch patterns.
    """

def calver_by_date(version: ScmVersion) -> str:
    """
    Calendar versioning scheme using current date.
    
    Examples:
    - Tag "2023.1.0" + commits → "2023.1.1.dev{distance}"
    """

Local Schemes

Functions that determine the local version identifier (part after + in version string).

def get_local_node_and_date(version: ScmVersion) -> str:
    """
    Default local scheme. Includes commit hash and date.
    
    Examples:
    - Clean repo → "" (no local part)
    - Dirty repo → "+g{node}.d20231201"
    - Commits after tag → "+g{node}.d20231201"
    """

def get_local_node_and_timestamp(version: ScmVersion) -> str:
    """
    Local scheme with commit hash and timestamp.
    
    Examples:
    - Dirty repo → "+g{node}.{timestamp}"
    """

def get_local_dirty_tag(version: ScmVersion) -> str:
    """
    Simple local scheme that only adds suffix for dirty repos.
    
    Examples:
    - Clean repo → "" (no local part)
    - Dirty repo → "+dirty"
    """

def get_no_local_node(version: ScmVersion) -> str:
    """
    No local version identifier scheme.
    
    Examples:
    - Any state → "" (no local part)
    """

Version Helper Functions

Utility functions for version processing and manipulation.

def tag_to_version(tag: str, config: Configuration) -> Version | None:
    """
    Convert a tag string to a Version object using tag regex.
    
    Parameters:
    - tag: Tag string from SCM
    - config: Configuration with tag_regex pattern
    
    Returns:
    Version object or None if tag doesn't match regex
    """

def meta(
    tag: str,
    *,
    distance: int = 0,
    dirty: bool = False,
    node: str | None = None,
    preformatted: bool = False,
    branch: str | None = None,
    config: Configuration,
    node_date: date | None = None
) -> ScmVersion:
    """
    Create ScmVersion object from tag metadata.
    
    Parameters:
    - tag: Version tag string
    - distance: Number of commits since tag
    - dirty: Whether working directory has uncommitted changes
    - node: Commit hash/node identifier
    - preformatted: Whether tag is already formatted
    - branch: Branch name
    - config: Configuration object
    - node_date: Date of the commit
    
    Returns:
    ScmVersion object with parsed metadata
    """

def format_version(version: ScmVersion, **kwargs) -> str:
    """
    Format ScmVersion to final version string using configured schemes.
    
    Parameters:
    - version: ScmVersion object to format
    - **kwargs: Additional formatting arguments
    
    Returns:
    Final formatted version string
    """

def guess_next_version(tag_version: ScmVersion) -> str:
    """
    Guess the next version based on current tag.
    Used internally by guess_next_dev_version scheme.
    
    Parameters:
    - tag_version: ScmVersion with current tag information
    
    Returns:
    Guessed next version string
    """

def guess_next_simple_semver(
    version: ScmVersion,
    retain: int,
    increment: bool = True
) -> str:
    """
    Guess next semantic version with configurable component retention.
    
    Parameters:
    - version: ScmVersion object
    - retain: Number of version components to retain (1=major, 2=minor, 3=patch)
    - increment: Whether to increment the last retained component
    
    Returns:
    Next semantic version string
    """

Usage Examples

Custom Version Schemes

from setuptools_scm import get_version

# Use different version schemes
dev_version = get_version(version_scheme="guess-next-dev")
post_version = get_version(version_scheme="post-release") 
exact_version = get_version(version_scheme="only-version")
semver_version = get_version(version_scheme="python-simplified-semver")

print(f"Dev: {dev_version}")       # e.g., "1.0.1.dev3+g1234567.d20231201"
print(f"Post: {post_version}")     # e.g., "1.0.0.post3+g1234567.d20231201"
print(f"Exact: {exact_version}")   # e.g., "1.0.0+g1234567.d20231201"
print(f"Semver: {semver_version}") # e.g., "1.0.1.dev3+g1234567.d20231201"

Custom Local Schemes

from setuptools_scm import get_version

# Use different local schemes
node_date = get_version(local_scheme="node-and-date")
node_timestamp = get_version(local_scheme="node-and-timestamp")
dirty_only = get_version(local_scheme="dirty-tag")
no_local = get_version(local_scheme="no-local-version")

print(f"Node+Date: {node_date}")       # e.g., "1.0.0+g1234567.d20231201"
print(f"Node+Time: {node_timestamp}")  # e.g., "1.0.0+g1234567.1701432000"
print(f"Dirty: {dirty_only}")          # e.g., "1.0.0+dirty" or "1.0.0"
print(f"No local: {no_local}")         # e.g., "1.0.0"

pyproject.toml Configuration

[tool.setuptools_scm]
version_scheme = "python-simplified-semver"
local_scheme = "no-local-version"
tag_regex = "^(?P<version>[vV]?\\d+(?:\\.\\d+){0,2}[^\\+]*)(?:\\+.*)?$"
fallback_version = "0.0.0"

Custom Schemes via Entry Points

You can define custom schemes by creating entry points in your package:

[project.entry-points."setuptools_scm.version_scheme"]
"my-custom-scheme" = "mypackage.version:my_version_scheme"

[project.entry-points."setuptools_scm.local_scheme"] 
"my-local-scheme" = "mypackage.version:my_local_scheme"
# mypackage/version.py
def my_version_scheme(version):
    """Custom version scheme implementation"""
    if version.exact:
        return str(version.tag)
    return f"{version.tag}.custom{version.distance}"

def my_local_scheme(version):
    """Custom local scheme implementation"""
    if version.dirty:
        return "+modified"
    return ""

Working with ScmVersion Objects

from setuptools_scm.version import meta
from setuptools_scm import Configuration

config = Configuration()

# Create ScmVersion manually (normally done internally)
scm_ver = meta(
    tag="1.0.0",
    distance=3,
    dirty=True,
    node="abc1234",
    branch="main",
    config=config
)

# Use built-in formatting methods
clean_fmt = scm_ver.format_choice("{tag}", "{tag}.dirty{distance}")
custom_fmt = scm_ver.format_with("v{tag}-{distance}-{node}")

print(f"Clean/Dirty: {clean_fmt}")  # "1.0.0.dirty3"
print(f"Custom: {custom_fmt}")      # "v1.0.0-3-abc1234"

Constants

DEFAULT_VERSION_SCHEME: str = "guess-next-dev"
DEFAULT_LOCAL_SCHEME: str = "node-and-date"
DEFAULT_TAG_REGEX: Pattern[str]  # Regex pattern: ^(?:[\w-]+-)?(?P<version>[vV]?\d+(?:\.\d+){0,2}[^\+]*)(?:\+.*)?$

Install with Tessl CLI

npx tessl i tessl/pypi-setuptools-scm

docs

cli.md

core-api.md

index.md

integration.md

version-schemes.md

tile.json