Skip to main content

calver-scm is a setuptools-scm plugin that generates CalVer version strings directly from your Git tags and commit history. No __version__ files to maintain, no manual bumping; just tag and go.

Versions look like this:

2026.4.0          -> clean tag, April 2026, patch 0
2026.4.1.dev3     -> 3 commits after that tag, still April, patch incremented
2026.5.0.dev3     -> 3 commits after an old tag, month rolled over, patch reset
2026.4.15.0       -> day mode: clean tag on the 15th
2026.4.15.1.dev2  -> day mode: 2 commits after a tag on the same day
2026.4.0.dev12    -> no tag yet, 12 commits in
0.2026.4.0        -> same release line, but marked unstable/pre-1.0

Installation

pip install calver-scm

Then wire it into your pyproject.toml. Pick the setup that matches your build backend:

If you use Hatchling, this is the shortest working setup:

[build-system]
requires = ["hatchling", "hatch-vcs", "calver-scm"]
build-backend = "hatchling.build"

[project]
dynamic = ["version"]

[tool.hatch.version]
source = "vcs"

[tool.hatch.version.raw-options]
version_scheme = "calver-scm"
local_scheme   = "dirty-tag"

dynamic = ["version"] is required so Hatch knows the version is resolved from VCS at build time.

With setuptools

[build-system]
requires = ["setuptools", "setuptools-scm", "calver-scm"]
build-backend = "setuptools.build_meta"

[project]
dynamic = ["version"]

[tool.setuptools_scm]
version_scheme = "calver-scm"
local_scheme   = "dirty-tag"

dynamic = ["version"] is required when using PEP 621 metadata in pyproject.toml.

hatch-vcs extras (optional)

The quickstart config above is enough for most projects. If you want a runtime __version__ file, hatch-vcs can write one during builds:

[tool.hatch.build.hooks.vcs]
version-file = "src/your_package/_version.py"

Then in your __init__.py:

from ._version import __version__

That's it. Your project will now version itself automatically on every build.

CI note

This plugin derives versions from Git history and tags. In CI, make sure your checkout includes tags and enough history to resolve the latest version tag.


How versions are generated

The generated version shape is config-driven. In general, it looks like:

[0.]<DATE_BASE>.PATCH[.devN][+local]
  • <DATE_BASE> comes from mode/scheme (for example YYYY, YYYY.MM, YYYY.WW, or YYYY.MM.DD).
  • 0. is included only when stable = false.
  • .devN appears for non-tag builds (and in no-tag fallback when fallback = "dev").
  • +local (including +dirty) depends on your setuptools-scm local_scheme.

If stable = false, calver-scm prefixes the generated public version with 0. to indicate an explicitly unstable release line:

2026.4.0      -> stable output (default)
0.2026.4.0    -> unstable output
0.2026.4.1.dev3
Situation Example
Clean tag, month mode 2026.4.0
Commits after tag, same month 2026.4.1.dev3
Commits after tag, previous month's tag 2026.5.0.dev3
Clean tag, day mode 2026.4.15.0
Dirty working tree 2026.4.0+dirty
No tag yet 2026.4.0.dev12

The patch segment increments automatically from your last tag within the current period, and resets to 0 whenever the month (or day, in day mode) rolls over.

The date segment is derived from the build/runtime date, not from commit timestamps.

Pre-release, post-release, and local tags

If your Git tag carries any PEP 440 suffix, calver-scm preserves it in the generated version and normalises it to its PEP 440 canonical form.

Pre-release suffixes (a, b, rc)

Tag any of the recognised PEP 440 aliases and it is normalised automatically:

Tag suffix Canonical output
alpha / a a
beta / b b
preview / pre / c / rc rc
v2026.4.0a1     -> 2026.4.0a1
v2026.4.0beta2  -> 2026.4.0b2
v2026.4.0pre1   -> 2026.4.0rc1
v2026.4.0rc1    -> 2026.4.0rc1

Post-release suffixes (post)

Tag suffix Canonical output
-rN / revN postN
post-N / postN postN
v2026.4.0-r1     -> 2026.4.0.post1
v2026.4.0.rev2   -> 2026.4.0.post2
v2026.4.0.post-3 -> 2026.4.0.post3
v2026.4.0.post3  -> 2026.4.0.post3

Dev suffixes (dev)

Tag suffix Canonical output
dev (bare) dev0
dev-N / devN devN
v2026.4.0.dev    -> 2026.4.0.dev0
v2026.4.0.dev-4  -> 2026.4.0.dev4
v2026.4.0.dev4   -> 2026.4.0.dev4

Local version segment (+)

A +local segment on a tag is preserved as-is. PEP 440 normalises underscores to dots within local identifiers:

v2026.4.0+abc            -> 2026.4.0+abc
v2026.4.0+linux.x86_64   -> 2026.4.0+linux.x86.64

Note: The +local segment on a tag is distinct from the +dirty suffix that setuptools-scm appends for uncommitted working-tree changes. See Local scheme for how to control that behaviour.

Combining suffixes

All segments can be combined and are each normalised independently:

v2026.4.0rc1.post2.dev3+local -> 2026.4.0rc1.post2.dev3+local

Configuration

Add a [tool.calver-scm] section to pyproject.toml to customise behaviour. All fields are optional, and the defaults shown below are sensible for most projects.

[tool.calver-scm]
mode       = "month"   # "year" | "month" | "week" | "day"
scheme     = "YYYY.MM" # optional token scheme; defaults from mode
patch      = true      # auto-increment patch within a period
stable     = true      # emit normal tags, or prefix versions with 0. when false
no_dev     = false     # suppress .devN suffix on non-exact versions
fallback   = "dev"     # "dev" | "date" (when no tag exists)
tag_prefix = "v"       # prefix stripped when reading tags
timezone   = "UTC"     # "UTC" (default), "local", or IANA tz name

If scheme is omitted, calver-scm uses sensible defaults:

  • mode = "year" -> YYYY
  • mode = "month" -> YYYY.MM
  • mode = "week" -> YYYY.WW
  • mode = "day" -> YYYY.MM.DD

Supported scheme tokens follow CalVer terminology: YYYY, YY, MM, WW, DD.

Week tokens (WW) cannot be combined with month/day tokens.

mode

Controls the time granularity of the version base.

  • "year": base is YYYY (e.g. 2026)
  • "month": base is YYYY.MM (e.g. 2026.4)
  • "week": base is YYYY.WW (e.g. 2026.16)
  • "day": base is YYYY.MM.DD (e.g. 2026.4.15)
# Year mode: annual cadence
[tool.calver-scm]
mode = "year"
# -> 2026.0, 2026.1.dev3 ...

# Month mode (default): good for most projects
[tool.calver-scm]
mode = "month"
# -> 2026.4.0, 2026.4.1.dev3, 2026.5.0.dev1 ...

# Week mode: weekly cadence
[tool.calver-scm]
mode = "week"
# -> 2026.16.0, 2026.16.1.dev2 ...

# Day mode: useful for projects that release frequently
[tool.calver-scm]
mode = "day"
# -> 2026.4.15.0, 2026.4.15.1.dev2, 2026.4.16.0.dev1 ...

scheme

Defines the date portion explicitly using CalVer tokens.

# Explicitly match the default month style
[tool.calver-scm]
scheme = "YYYY.MM"

# Short year + month
[tool.calver-scm]
scheme = "YY.MM"
# -> 26.4.0, 26.4.1.dev3

# Year + ISO week (week schemes are month/day-exclusive)
[tool.calver-scm]
scheme = "YYYY.WW"
# -> 2026.16.0, 2026.16.1.dev2

patch

When true, the patch number increments from the last tag within the same period. When false, patch is always 0 and only the .devN distance distinguishes pre-release builds.

# patch = true (default): each build within a period gets a unique patch number
[tool.calver-scm]
patch = true
# tag v2026.4.2, then 3 commits later -> 2026.4.3.dev3

# patch = false: patch stays 0, only devN changes
[tool.calver-scm]
patch = false
# tag v2026.4.2, then 3 commits later -> 2026.4.0.dev3

stable

Controls whether generated public versions are emitted as stable releases or explicitly marked as unstable with a leading 0. prefix.

# stable = true (default): emit standard CalVer versions
[tool.calver-scm]
stable = true
# tag v2026.4.2, then 3 commits later -> 2026.4.3.dev3

# stable = false: prefix generated output with 0.
[tool.calver-scm]
stable = false
# tag v2026.4.2, then 3 commits later -> 0.2026.4.3.dev3

While stable = false, both v0.2026.4.3 and legacy unprefixed tags like v2026.4.3 are accepted as parseable historical bases to ease migration. When you switch to stable = true, tags that still carry the unstable 0. prefix are treated as incompatible and the version scheme falls back until you create the first stable tag.

For a go-live cutover, the recommended flow is:

  1. develop and pre-release with stable = false
  2. flip to stable = true on the release commit
  3. create the first stable tag, for example v2026.4.0

That keeps the unstable 0. tag line distinct from the stable release line and avoids silently reinterpreting old unstable tags as stable ones.

no_dev

When true, suppresses the .devN suffix on generated versions, emitting a clean {base}.{patch} version even when commits exist after the latest tag or when falling back in an untagged repository.

# no_dev = false (default): normal development versions with distance suffix
[tool.calver-scm]
no_dev = false
# tag v2026.4.2, then 3 commits later -> 2026.4.3.dev3

# no_dev = true: suppress dev suffix for release workflows
[tool.calver-scm]
no_dev = true
# tag v2026.4.2, then 3 commits later -> 2026.4.3

This is especially useful in release CI workflows that compute the clean target release version, create the tag, and publish the release in one pass without requiring a separate bumping step.

Note: no_dev only suppresses the public .devN version segment. Setuptools-scm's local_scheme (such as the default node-and-date) can still append a +g... local segment on untagged commits. Pair no_dev = true / CALVER_SCM_NO_DEV=true with a distance-insensitive local scheme like dirty-tag or no-local-version (or CI overrides like no-local-version-strict) to ensure a clean version string.

fallback

Controls what happens when no tag exists yet in the repository.

  • "dev": emits YYYY.MM.0.devN where N is the total commit count (default)
  • "date": emits YYYY.MM.0 with no dev segment, useful for initial releases
# fallback = "dev" (default): makes it clear this is a pre-release build
[tool.calver-scm]
fallback = "dev"
# 12 commits, no tag yet -> 2026.4.0.dev12

# fallback = "date": emits a clean version even before the first tag
[tool.calver-scm]
fallback = "date"
# 12 commits, no tag yet -> 2026.4.0

tag_prefix

The string that must prefix a tag for it to be recognised as a CalVer tag. Set to "" if your tags have no prefix.

# tag_prefix = "v" (default): tags like v2026.4.0
[tool.calver-scm]
tag_prefix = "v"

# No prefix: tags like 2026.4.0
[tool.calver-scm]
tag_prefix = ""

# Custom prefix: tags like release-2026.4.0
[tool.calver-scm]
tag_prefix = "release-"

timezone

Controls which timezone is used to compute the date segment.

  • "UTC": default; deterministic across environments
  • "local": machine local timezone
  • Any valid IANA timezone, e.g. "Europe/London", "America/New_York"
# Default, recommended for CI/reproducibility
[tool.calver-scm]
timezone = "UTC"

# Use host local timezone
[tool.calver-scm]
timezone = "local"

# Explicit IANA timezone
[tool.calver-scm]
timezone = "Pacific/Auckland"

Environment variable overrides

Every option can be overridden at build time without touching pyproject.toml, which is handy for CI pipelines.

Variable Equivalent option
CALVER_SCM_MODE mode
CALVER_SCM_SCHEME scheme
CALVER_SCM_PATCH patch (true / false)
CALVER_SCM_STABLE stable (true / false)
CALVER_SCM_NO_DEV no_dev (true / false)
CALVER_SCM_FALLBACK fallback
CALVER_SCM_TAG_PREFIX tag_prefix
CALVER_SCM_TIMEZONE timezone

Environment variables take precedence over pyproject.toml.


Local scheme

calver-scm controls the public version segment only. The +dirty suffix is handled separately by setuptools-scm's built-in local schemes. Pick whichever suits you:

[tool.setuptools_scm]
version_scheme = "calver-scm"
local_scheme   = "dirty-tag"         # +dirty on uncommitted changes (recommended)
# local_scheme = "no-local-version"  # suppress the local segment entirely
# local_scheme = "node-and-date"     # +g1a2b3c4.d20260415 (setuptools-scm default)

Requirements

  • Python >= 3.10
  • setuptools-scm >= 10.0.5
  • tomli >= 2.4.1 on Python < 3.11 (the stdlib tomllib is used on 3.11+)

License

MIT

Metadata

Release files for calver-scm 1.5.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for calver-scm 1.5.1
File Size Uploaded
calver_scm-1.5.1.tar.gz 90.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for calver-scm 1.5.1
File Interpreter ABI Platform
calver_scm-1.5.1-py3-none-any.whl Python 3 none any Details

Total release size: 105.5 kB

Release files / calver_scm-1.5.1.tar.gz

Download URL calver_scm-1.5.1.tar.gz
Size 90.5 kB
Tags Source
SHA-256 checksum
How to use checksums
958e8ce0f10db19bfdd2aad4579a32c632dcf1928c31558814cf8466a95db6ff
BLAKE2b-256 checksum
How to use checksums
7888b6447869e1d0b8a60569ddff0c479cf6fdee6a6878d2df3aa19dbc57f0b3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.13 {"installer":{"name":"uv","version":"0.12.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / calver_scm-1.5.1-py3-none-any.whl

Download URL calver_scm-1.5.1-py3-none-any.whl
Size 15.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3aaeb6b40376623ce9b2df564f622c692fae8828bd2c3a5e196e276a1839ef92
BLAKE2b-256 checksum
How to use checksums
aef18ca148167bfa3f5737019b791cc10e5eb5c1a06d815b1318d1b37cdb3ddf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.13 {"installer":{"name":"uv","version":"0.12.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

1.5.1 This release

2 release files

1.5.0

2 release files

1.4.1

2 release files

1.4.0

2 release files

1.3.4

2 release files

1.3.3

2 release files

1.3.2

2 release files

1.3.1

2 release files

1.3.0

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page