I love the way CMake allows me to single source version my C/C++ projects, by letting me say:
project(Tutorial VERSION 1.0)
in my CMakeLists.txt
file and, then, use placeholders of the form:
#define ver_maj @Tutorial_VERSION_MAJOR@
#define ver_min @Tutorial_VERSION_MINOR@
in my *.h.in
file, which, when run through configure_file()
, becomes:
#define ver_maj 1
#define ver_min 0
in my equivalent *.h
file.
I'm then able to include that file anywhere I need access to my project version numbers.
This is decidedly different than the experience I have with Python projects.
In that case, I'm often rebuilding, because I forgot to sync. up the version numbers in my pyproject.toml
and <module>/__init__.py
files.
What is the preferred way to achieve something similar to CMake style single source project versioning in a Python project?
In the __init__.py
you can set the __version__
like this:
from importlib.metadata import version as _get_version
# Set PEP396 version attribute
__version__ = _get_version('<put-your-package-name-here>')
Or, if your package targeted older Python:
import sys
if sys.version_info >= (3, 8):
from importlib.metadata import version as _get_version
else:
from importlib_metadata import version as _get_version
# …
and a package requirement:
importlib-metadata = {version = ">= 3.6", markers="python_version < '3.8'"}
(use the proper syntax for your build tool)
Also, there are some extensions for build tools (e.g., setuptools-scm
or hatch-vcs
) that allows avoiding setting explicit version in the pyproject.toml
for the sake of e.g., git
. So, the only source of version becomes VCS used.