In Version Numbering in Python Package I showed a way to store the package version number in the code. The method is in hindsight not exactly the best one (who knew!), so here is another try for simple projects.
Here I have
mypackage/
(the package directory)mypackage/__init__.py
mypackage/version.py
setup.py
with contents:
mypackage/version.py
:
__version__ = "1.2.3"
mypackage/__init__.py
:
from .version import __version__ # plus whatever things my package actually offers or does
setup.py
:
from pathlib import Path from setuptools import setup def get_version(pkg_name): version_filename = Path(__file__).parent / pkg_name / "version.py" with open(version_filename) as f: for line in f.readlines(): if line.startswith("__version__"): sep = '"' if '"' in line else "'" return line.split(sep)[1] raise RuntimeError(f"Version not found in {version_filename}") PACKAGE_NAME = "mypackage" setup( name=PACKAGE_NAME, version=get_version(PACKAGE_NAME), description="My Package", packages=[PACKAGE_NAME], )
What does it do?
- It has the package name as a constant (
PACKAGE_NAME
) insetup.py
get_version()
reads the version number fromversion.py
What are the benefits of this arrangement?
- Version number is only stored in one place, and it is accessible runtime as
mypackage.__version__
- Package name is not repeated in
setup.py
- There is no package import in
setup.py
, which avoids certain problem situations (like,setup.py
hasinstall_requires
list defined and the package imports those required packages; it will result in module import errors during the package install unless the required packages happen to be installed already)
After installing the package with “pip install .
“:
(mypackagevenv) markku@btest:~$ pip list Package Version ------------- ------- mypackage 1.2.3 pip 20.3.3 pkg-resources 0.0.0 setuptools 40.8.0 wheel 0.36.2 (mypackagevenv) markku@btest:~$ python Python 3.7.3 (default, Jul 25 2020, 13:03:44) [GCC 8.3.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import mypackage >>> mypackage.__version__ '1.2.3' >>>
More ideas and information about storing the version numbers: Single-sourcing the package version (in packaging.python.org)