.. _versions: 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: ``setuptools_scm`` ------------------ ``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 :ref:`data`. ``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 :ref:`releasing`) or when someone accesses ``my_package.__version__``. 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 ``my_package``. .. _dev-versions: 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 run ``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 ``_version.py`` will 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 ``__version__`` with ``setuptools_scm``, however, you don't want to do this for non-development installations as it's slow and requires ``setuptools_scm`` to be installed. 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 excluded in ``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 access ``_dev`` (in the case where it's not a dev install).