How could I get the version defined in setup.py
from my package (for --version
, or other purposes)?
There's a thousand ways to skin a cat -- here's mine:
# Copied from (and hacked):
# https://github.com/pypa/virtualenv/blob/develop/setup.py#L42
def get_version(filename):
import os
import re
here = os.path.dirname(os.path.abspath(__file__))
f = open(os.path.join(here, filename))
version_file = f.read()
f.close()
version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]",
version_file, re.M)
if version_match:
return version_match.group(1)
raise RuntimeError("Unable to find version string.")
Cleaning up https://stackoverflow.com/a/12413800 from @gringo-suave:
from itertools import ifilter
from os import path
from ast import parse
with open(path.join('package_name', '__init__.py')) as f:
__version__ = parse(next(ifilter(lambda line: line.startswith('__version__'),
f))).body[0].value.s
The best technique is to define __version__
in your product code, then import it into setup.py from there. This gives you a value you can read in your running module, and have only one place to define it.
The values in setup.py are not installed, and setup.py doesn't stick around after installation.
What I did (for example) in coverage.py:
# coverage/__init__.py
__version__ = "3.2"
# setup.py
from coverage import __version__
setup(
name = 'coverage',
version = __version__,
...
)
UPDATE (2017): coverage.py no longer imports itself to get the version. Importing your own code can make it uninstallable, because you product code will try to import dependencies, which aren't installed yet, because setup.py is what installs them.
I am using an environment variable as below
VERSION=0.0.0 python setup.py sdist bdist_wheel
In setup.py
import os
setup(
version=os.environ['VERSION'],
...
)
For consistency check with packer version, I am using below script.
PKG_VERSION=`python -c "import pkg; print(pkg.__version__)"`
if [ $PKG_VERSION == $VERSION ]; then
python setup.py sdist bdist_wheel
else
echo "Package version differs from set env variable"
fi
deploy package to server and file naming convention for indices packages :
example for pip dynamic version conversion:
win:
mac:
from setuptools_scm import get_version
def _get_version():
dev_version = str(".".join(map(str, str(get_version()).split("+")[0]\
.split('.')[:-1])))
return dev_version
Find the sample setup.py calls the dynamic pip version matching from git commit
setup(
version=_get_version(),
name=NAME,
description=DESCRIPTION,
long_description=LONG_DESCRIPTION,
classifiers=CLASSIFIERS,
# add few more for wheel wheel package ...conversion
)
Now this is gross and needs some refining (there may even be an uncovered member call in pkg_resources that I missed), but I simply do not see why this doesn't work, nor why no one has suggested it to date (Googling around has not turned this up)...note that this is Python 2.x, and would require requiring pkg_resources (sigh):
import pkg_resources
version_string = None
try:
if pkg_resources.working_set is not None:
disto_obj = pkg_resources.working_set.by_key.get('<my pkg name>', None)
# (I like adding ", None" to gets)
if disto_obj is not None:
version_string = disto_obj.version
except Exception:
# Do something
pass