What is the correct way to share package version with setup.py and the package?
distutils, python, setuptools
Solution
Set the version in `setup.py` only, and read your own version with `pkg_resources`, effectively querying the `setuptools` metadata:
file: `setup.py`
setup(
name='foobar',
version='1.0.0',
# other attributes
)
file: `__init__.py`
from pkg_resources import get_distribution
__version__ = get_distribution('foobar').version
To make this work in all cases, where you could end up running this without having installed it, test for `DistributionNotFound` and the distribution location:
from pkg_resources import get_distribution, DistributionNotFound
import os.path
try:
_dist = get_distribution('foobar')
# Normalize case for Windows systems
dist_loc = os.path.normcase(_dist.location)
here = os.path.normcase(__file__)
if not here.startswith(os.path.join(dist_loc, 'foobar')):
# not installed, but there is another version that *is*
raise DistributionNotFound
except DistributionNotFound:
__version__ = 'Please install this project with setup.py'
else:
__version__ = _dist.version
Problem
With `distutils`, `setuptools`, etc. a package version is specified in `setup.py`: ``` # file: setup.py ... setup( name='foobar', version='1.0.0', # other attributes ) ``` I would like to be able to access the same version number from within the package: ``` >>> import foobar >>> foobar.__version__ '1.0.0' ``` I could add `__version__ = '1.0.0'` to my package's __init__.py, but I would also like to include additional imports in my package to create a simplified interface to the package: ``` # file: __init__.py from foobar import foo from foobar.bar import Bar __version__ = '1.0.0' ``` and ``` # file: setup.py from foobar import __version__ ... setup( name='foobar', version=__version__, # other attributes ) ``` However, these additional imports can cause the installation of `foobar` to fail if they import other packages that are not yet installed. What is the correct way to share package version with setup.py and the package?