Retrieving package version at runtime¶
Using version_file option (recommended)¶
In case of using version_file option you can directly read the VERSION file content,
and use at as version number.
To resolve version number in runtime, you should move VERSION file to your module subfolder:
Create MANIFEST.in file in the project root:
include my_module/VERSION
Then make few changes in setup.py:
from path import Path
root_path = Path(__file__).parent
version_file = root_path / "my_module" / "VERSION"
setuptools.setup(
...,
setup_requires=["setuptools-git-versioning>=3.0,<4"],
setuptools_git_versioning={
"enabled": True,
"version_file": version_file,
},
# read MANIFEST.in and include files mentioned here to the package
include_package_data=True,
# this package will read some included files in runtime, avoid installing it as .zip
zip_safe=False,
)
[build-system]
requires = [ "setuptools>=41", "wheel", "setuptools-git-versioning>=3.0,<4", ]
build-backend = "setuptools.build_meta"
[project]
dynamic = ["version"]
[tool.setuptools.package-data]
# include VERSION file to a package
my_module = ["VERSION"]
[tool.setuptools]
# this package will read some included files in runtime, avoid installing it as .zip
zip-safe = false
[tool.setuptools-git-versioning]
enabled = true
# change the file path
version_file = "my_module/VERSION"
And then read this file:
from pathlib import Path
# you can use os.path and open() as well
__version__ = Path(__file__).parent.joinpath("VERSION").read_text()
Using version_callback option¶
In case of using version_callback option you can directly call this callback inside a module:
from my_module.version import get_version
__version__ = get_version()
Using importlib¶
If you have opted not to hardcode the version number inside the package,
you can retrieve it at runtime from PEP 0566 metadata using
importlib.metadata from the standard library (added in Python 3.8)
or the importlib_metadata backport:
from importlib.metadata import version, PackageNotFoundError
try:
__version__ = version("package-name")
except PackageNotFoundError:
# package is not installed
pass
Using pkg_resources¶
In some cases importlib cannot properly detect package version,
for example it was compiled into executable file, so it uses some
custom import mechanism.
Instead, you can use pkg_resources which is included in setuptools
(but has a significant runtime cost):
from pkg_resources import get_distribution, DistributionNotFound
try:
__version__ = get_distribution("package-name").version
except DistributionNotFound:
# package is not installed
pass
However, this does place a runtime dependency on setuptools, and can add up to a few 100ms overhead for the package import time.
Calling internals of setuptools_git_versioning module¶
Warning
This way is STRONGLY DISCOURAGED. Functions in the module are not a part of public API, and could be changed in the future without maintaining backward compatibility.
Warning
Use this ONLY in CI/CD tools.
NEVER use setuptools_git_versioning inside your package, because .git
folder is not being included into it, and target OS can lack of git executable.
.git folder and git executable presence is crucial
for setuptools-git-versioning to work properly.
from setuptools_git_versioning import get_version, get_tag, get_all_tags
# uses setup.py or pyproject.toml as config source
version = get_version()
# calls `git` executable to get latest tag merged into HEAD history tree
latest_tag = get_tag()
# calls `git` executable to get all the tags in the repo
all_tags = get_all_tags()