Skip to content

Customizing

providing project local version schemes

As PEP 621 provides no way to specify local code as a build backend plugin, setuptools_scm has to piggyback on setuptools for passing functions over.

To facilitate that one needs to write a setup.py file and pass partial setuptools_scm configuration in via the use_scm_version keyword.

It's strongly recommended to experiment with using stock version schemes or creating plugins as package. (This recommendation will change if there ever is something like build-time entrypoints).

file: docs/examples/version_scheme_code/setup.py
# we presume installed build dependencies
from __future__ import annotations

from setuptools import setup

from setuptools_scm import ScmVersion


def myversion_func(version: ScmVersion) -> str:
    from setuptools_scm.version import guess_next_version

    return version.format_next_version(guess_next_version, "{guessed}b{distance}")


setup(use_scm_version={"version_scheme": myversion_func})
file: docs/examples/version_scheme_code/pyproject.toml
[build-system]
requires = ["setuptools>=64", "setuptools_scm>=8"]
build-backend = "setuptools.build_meta"

[project]
name = "scm-example"
dynamic = [
  "version",
]

[tool.setuptools_scm]
  • add a build block that adds example output

Importing in setup.py

With the pep 517/518 build backend, setuptools_scm is importable from setup.py

setup.py
import setuptools
from setuptools_scm.version import get_local_dirty_tag

def clean_scheme(version):
    return get_local_dirty_tag(version) if version.dirty else '+clean'

setup(use_scm_version={'local_scheme': clean_scheme})

alternative version classes

setuptools_scm.NonNormalizedVersion

Bases: Version

A non-normalizing version handler.

You can use this class to preserve version verification but skip normalization. For example you can use this to avoid git release candidate version tags ("1.0.0-rc1") to be normalized to "1.0.0rc1". Only use this if you fully trust the version tags.

Source code in src/setuptools_scm/_version_cls.py
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
class NonNormalizedVersion(Version):
    """A non-normalizing version handler.

    You can use this class to preserve version verification but skip normalization.
    For example you can use this to avoid git release candidate version tags
    ("1.0.0-rc1") to be normalized to "1.0.0rc1". Only use this if you fully
    trust the version tags.
    """

    def __init__(self, version: str) -> None:
        # parse and validate using parent
        super().__init__(version)

        # store raw for str
        self._raw_version = version

    def __str__(self) -> str:
        # return the non-normalized version (parent returns the normalized)
        return self._raw_version

    def __repr__(self) -> str:
        # same pattern as parent
        return f"<NonNormalizedVersion({self._raw_version!r})>"