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

integration.mddocs/

Build System Integration

setuptools-scm provides seamless integration with setuptools, modern build systems, and packaging tools through entry points, hooks, and configuration. This enables automatic version inference and SCM-managed file inclusion in Python packages.

from pathlib import Path
from typing import Any, Sequence
from os import PathLike

# Type Aliases (from setuptools_scm)
PathT = PathLike[str] | str

Capabilities

File Discovery

Functions for finding and listing SCM-managed files for inclusion in source distributions.

def find_files(path: PathT = "") -> list[str]:
    """
    Find SCM-managed files for setuptools integration.
    
    Parameters:
    - path: Root path to search for files (default: current directory)
    
    Returns:
    List of file paths managed by SCM
    """

Version File Generation

Functions for writing version information to files during build or development.

def dump_version(
    root: PathT,
    version: str,
    write_to: PathT,
    template: str | None = None,
    scm_version: ScmVersion | None = None
) -> None:
    """
    Write version information to a file (soft deprecated).
    
    Parameters:  
    - root: Repository root directory
    - version: Version string to write
    - write_to: Path to write version file to
    - template: Template for version file content (uses default if None)
    - scm_version: ScmVersion object for additional metadata
    """

def write_version_to_path(
    target: Path,
    template: str | None = None,
    version: str,
    scm_version: ScmVersion | None = None  
) -> None:
    """
    Write version to specific path with template.
    
    Parameters:
    - target: Target file path
    - template: Template for file content
    - version: Version string
    - scm_version: ScmVersion object for metadata
    """

SCM File Finders

Specialized file finders for different SCM systems, accessible via entry points.

# Git file finders
def git_find_files(path: str) -> list[str]:
    """Find files managed by Git"""

def git_archive_find_files(path: str) -> list[str]:
    """Find files from Git archive metadata"""

# Mercurial file finders  
def hg_find_files(path: str) -> list[str]:
    """Find files managed by Mercurial"""

def hg_archive_find_files(path: str) -> list[str]:
    """Find files from Mercurial archive metadata"""

Setuptools Hooks

Integration points for setuptools to automatically infer versions and find files.

def version_keyword(dist, keyword, value):
    """Handle use_scm_version keyword in setup.py (legacy)"""

def infer_version(dist):
    """Automatically infer version for setuptools during build"""

Utility Functions

Helper functions for parsing and processing integration data.

def data_from_mime(path: str, content: str | None = None) -> dict[str, str]:
    """
    Return mapping from MIME/pseudo-MIME content.
    
    Parameters:
    - path: File path
    - content: File content (reads from path if None)
    
    Returns:
    Dictionary mapping parsed from MIME-like content
    """

Entry Point System

setuptools-scm uses Python's entry point system to provide extensible plugin architecture:

SCM Parsers

# Entry point group: "setuptools_scm.parse_scm"
".git" = "setuptools_scm.git:parse"
".hg" = "setuptools_scm.hg:parse"

# Entry point group: "setuptools_scm.parse_scm_fallback" 
".git_archival.txt" = "setuptools_scm.git:parse_archival"
".hg_archival.txt" = "setuptools_scm.hg:parse_archival"
"PKG-INFO" = "setuptools_scm.fallbacks:parse_pkginfo"
"pyproject.toml" = "setuptools_scm.fallbacks:fallback_version"
"setup.py" = "setuptools_scm.fallbacks:fallback_version"

File Finders

# Entry point group: "setuptools_scm.files_command"
".git" = "setuptools_scm._file_finders.git:git_find_files" 
".hg" = "setuptools_scm._file_finders.hg:hg_find_files"

# Entry point group: "setuptools_scm.files_command_fallback"
".git_archival.txt" = "setuptools_scm._file_finders.git:git_archive_find_files"
".hg_archival.txt" = "setuptools_scm._file_finders.hg:hg_archive_find_files"

Setuptools Integration

# Entry point group: "distutils.setup_keywords"
"use_scm_version" = "setuptools_scm._integration.setuptools:version_keyword"

# Entry point group: "setuptools.file_finders"
"setuptools_scm" = "setuptools_scm._file_finders:find_files"

# Entry point group: "setuptools.finalize_distribution_options"
"setuptools_scm" = "setuptools_scm._integration.setuptools:infer_version"

Usage Examples

pyproject.toml Configuration

Modern Python packaging with PEP 518/621 support:

[build-system]
requires = ["setuptools>=64", "setuptools-scm>=8"]
build-backend = "setuptools.build_meta"

[project]
name = "mypackage"
dynamic = ["version"]
dependencies = ["requests", "click"]

[tool.setuptools_scm]
version_file = "src/mypackage/_version.py"
version_file_template = '''
# File generated by setuptools-scm
__version__ = "{version}"
__version_tuple__ = {version_tuple}
'''

Version File Generation

# Configuration with version file
from setuptools_scm import get_version

version = get_version(
    write_to="src/mypackage/_version.py",
    write_to_template='''
__version__ = "{version}"
__version_tuple__ = {version_tuple}
'''
)

# The generated file will contain:
# __version__ = "1.2.3.dev4+g1234567.d20231201"
# __version_tuple__ = ('1', '2', '3', 'dev4', 'g1234567', 'd20231201')

Legacy setup.py Integration

# setup.py (legacy approach)
from setuptools import setup

setup(
    name="mypackage",
    use_scm_version=True,
    setup_requires=["setuptools-scm"],
    # ... other setup parameters
)

# With custom configuration
setup(
    name="mypackage", 
    use_scm_version={
        "version_scheme": "python-simplified-semver",
        "local_scheme": "no-local-version",
        "write_to": "mypackage/_version.py"
    },
    setup_requires=["setuptools-scm"],
)

Build Tool Integration

# Using build (PEP 517)
python -m build

# Using pip
pip install -e .

# Using setuptools directly
python setup.py sdist bdist_wheel

All these tools automatically pick up setuptools-scm configuration and use it for version determination.

File Finder Usage

from setuptools_scm._file_finders import find_files

# Find all SCM-managed files
files = find_files(".")
print("SCM-managed files:", files)

# This is used internally by setuptools to include files in sdist

Custom Entry Points

You can extend setuptools-scm with custom entry points:

# In your package's pyproject.toml
[project.entry-points."setuptools_scm.version_scheme"]
"my-custom-scheme" = "mypackage.scm:my_version_scheme"

[project.entry-points."setuptools_scm.local_scheme"]
"my-local-scheme" = "mypackage.scm:my_local_scheme"

[project.entry-points."setuptools_scm.parse_scm"]
".myvcm" = "mypackage.scm:parse_my_vcm"
# mypackage/scm.py
def my_version_scheme(version):
    """Custom version scheme"""
    return f"custom-{version.tag}"

def my_local_scheme(version):
    """Custom local scheme"""
    return f"+build{version.distance}" if version.distance else ""

def parse_my_vcm(root, config):
    """Custom VCS parser"""
    # Implementation for custom version control system
    pass

CI/CD Integration Examples

GitHub Actions

name: Build and Release
on: [push, pull_request]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
      with:
        fetch-depth: 0  # Required for setuptools-scm
    
    - name: Set up Python
      uses: actions/setup-python@v4
      with:
        python-version: "3.11"
    
    - name: Install dependencies
      run: |
        pip install build setuptools-scm
    
    - name: Get version
      run: |
        VERSION=$(python -m setuptools_scm)
        echo "VERSION=$VERSION" >> $GITHUB_ENV
        echo "Building version: $VERSION"
    
    - name: Build package
      run: python -m build

GitLab CI

build:
  stage: build
  script:
    - pip install build setuptools-scm
    - VERSION=$(python -m setuptools_scm --strip-dev)
    - echo "Building version $VERSION"
    - python -m build
  artifacts:
    paths:
      - dist/

Docker Integration

FROM python:3.11-slim

# Install git for setuptools-scm
RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*

COPY . /app
WORKDIR /app

# setuptools-scm will automatically determine version
RUN pip install -e .

# Version information available at runtime
RUN python -c "import mypackage; print(mypackage.__version__)"

Runtime Version Access

# In your package's __init__.py
from importlib.metadata import version, PackageNotFoundError

try:
    __version__ = version("mypackage")
except PackageNotFoundError:
    # Development installation
    from setuptools_scm import get_version
    __version__ = get_version(root="..")

Or with generated version file:

# In your package's __init__.py
try:
    from ._version import __version__
except ImportError:
    # Fallback for development
    from setuptools_scm import get_version
    __version__ = get_version(root="..")

Template Formats

Python Version File Template

# Default template for .py files
TEMPLATE_PY = '''
# file generated by setuptools-scm
# don't change, don't track in version control

__all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]

__version__ = version = {version!r}
__version_tuple__ = version_tuple = {version_tuple!r}
'''

Text File Template

# Default template for .txt files
TEMPLATE_TXT = "{version}"

Custom Templates

# Custom template example
custom_template = '''
"""Version information for {dist_name}"""
VERSION = "{version}"
BUILD_DATE = "{build_date}"
COMMIT = "{node}"
DIRTY = {dirty}
'''

version = get_version(
    write_to="mypackage/_version.py",
    write_to_template=custom_template
)

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