Specifying the Version of your Package¶
Synchronising the version information about your package between, the git repository, the python source code and the python package metadata can be complex.
We strongly recommend using setuptools_scm to do this. With a little effort and understanding it is possible to make the git history the single source of truth for all your version information, for your releases and any development installs.
setuptools_scm is an extension to the
setuptools package, which performs two functions:
It calculates the version number from the git history.
It uses the git repository to get a list of all files to include in the package.
This section is focusing on the first one, the second is discussed in Including data in your package.
setuptools_scm works by calling
$ git describe which returns information
about the current version of the repository, based on distance away from the
last tag on the current branch.
This means that with a little parsing, this information can be used to determine
the version of the package at the point where you build packages to release them on
PyPI (as described in Releasing Your Package) or when someone accesses
When just considering these built packages
setuptools_scm works by running
git describe at the time you build the package and then saving the output
into the code (if configured) and metadata of the package. If you use the
default configuration of the template included with this guide, after installing
the package the contents of the
my_package/_version.py file would be:
# coding: utf-8 # file generated by setuptools_scm # don't change, don't track in version control __version__ = version = '0.1.dev0' __version_tuple__ = version_tuple = (0, 1, 'dev0')
This file is used to provide the
__version__ attribute of
Dynamic Development Versions¶
The final piece of this puzzle is versions for packages installed in “editable”
mode from a git repository. By default when using
setuptools_scm when you
pip install -e ./ in your git checkout, it will run
git describe and
encode the current version into the
_version.py file described above. The
problem with this approach is that the version number in
not change, as you make new commits or even add new tags.
The solution to this is to dynamically calculate the version on access of
setuptools_scm, however, you don’t want to do this for
non-development installations as it’s slow and requires
The solution to this implemented in the template (behind an opt-in option) is to
make a subpackage called _dev which is not included in the dists (it is
MANIFEST.in) which invokes setuptools. This
_dev package is
then invoked by the
my_pacakge/version.py file, which will fall back to
reading the static version from
my_package/_version.py file if it can’t
_dev (in the case where it’s not a dev install).