Reputation: 105
When I use pip to install a package from source, it will generates a version number for the package which I can see using 'pip show '. But I can't find out how that version number is generated and I can't find the version string from the source code. Can someone tell me how the version is generated?
Upvotes: 4
Views: 2592
Reputation: 23559
Instead of specifying the version number in code, tools such as setuptools-scm
may use tags from version control. Sometimes the magic is not directly visible. For example PyScaffold uses it, but in the project's root folder's __init__.py
one may just see:
import pkg_resources
try:
__version__ = pkg_resources.get_distribution(__name__).version
except:
__version__ = "unknown"
If, for example, the highest version tag in Git is 6.10.0, then pip install -e .
will generate a local version number such as 6.10.0.post0.dev23+ngc376c3c
(c376c3c
being the short hash of the last commit) or 6.10.0.post0.dev23+ngc376c3c.dirty
(if it has uncommitted changes).
Upvotes: 1
Reputation: 17037
For more complicated strings such as 4.0.0rc1
, they are usually hand edited in the PKG-INFO
file. Such as:
# cat ./<package-name>.egg-info/PKG-INFO
...
Version: 4.0.0rc1
...
This make it unfeasible to obtain it from within any python code.
Upvotes: 0
Reputation: 366003
The version number that pip
uses comes from the setup.py
(if you pip install
a file, directory, repo, etc.) and/or the information in the PyPI index (if you pip install
a package name). (Since these two must be identical, it doesn't really matter which.)
It's recommended that packages make the same string available as a __version__
attribute on their top-level module/package(s) at runtime that they put in their setup, but that isn't required, and not every package does.
And if the package doesn't expose its version, there's really no way for you to get it. (Well, unless you want to grub through the pip
data trying to figure out which package owns a module and then get its version.)
Here's an example:
In the source code for bs4
(BeautifulSoup4), the setup.py
file has this line:
version = "4.3.2",
That's the version that's used, directly or indirectly, by pip
.
Then, inside bs4/__init__.py
, there's this line:
__version__ = "4.3.2"
That means that Leonard Richardson is a nice guy who follows the recommendations, so I can import bs4; print(bs4.__version__)
and get back the same version string that pip show beautifulsoup4
gives me.
But, as you can see, they're two completely different strings in completely different files. If he wasn't nice, they could be totally different, or the second one could be missing, or named something different.
The OpenStack people came up with a nifty library named PBR that helps you manage version numbers. You can read the linked doc page for the full details, but the basic idea is that it either generates the whole version number for you out of git, or verifies your specified version number (in the metadata
section of setup.cfg
) and appends the dev
build number out of git. (This relies on you using Semantic Versioning in your git
repo.)
Upvotes: 5