I found it quite unreliable to use the various tools available (including the best one pkg_resources
mentioned by moraes' answer), as most of them do not cover all cases.
Version numbers in python can be in very different places depending on the case:
for modules and packages, on the optional __version__
attribute as recommended by PEP396. It should be considered inherited by subpackages and submodules by default if they do not have the attribute.
for distributed modules and packages, on the Version
Metadata field as indicated by PEP345, that is located:
- for built wheels distributions (PEP427), on the
dist-info
directory, but also in the dist-info folder name
- for built eggs distributions (legacy format from setuptools), on the
egg-info
directory, but is also in the egg-info folder name
finally, for built-in modules and packages, the default version should be inherited from the python system version except if overridden
In addition to this, at runtime (when you need that version number), packages and modules can be
- already imported or not
- built and pip-installed (in debug mode or not), or simply added to the PYTHON PATH (sys.path)
- non-built and added to the PYTHON PATH (sys.path)
This variety of settings makes it very difficult for existing solutions to tackle all aspects of this problem. pkg_resources
is probably the best way to get it as of today, but does not work for example when a package is an unzipped wheel added to the PYTHON PATH. It also does not support built-in modules.
Since we needed a reliable way to get the version of any package, module or submodule, I ended up writing getversion. It implements a series of strategies in sequence, until something works.
It is quite simple to use:
from getversion import get_module_version
# Get the version of an imported module
from xml import dom
version, details = get_module_version(dom)
In particular the details
provide useful hints about how the version flag was retrieved:
> print(details)
Version '3.7.3.final.0' found for module 'xml.dom' by strategy 'get_builtin_module_version', after the following failed attempts:
- Attempts for module 'xml.dom':
- <get_module_version_attr>: module 'xml.dom' has no attribute '__version__'
- Attempts for module 'xml':
- <get_module_version_attr>: module 'xml' has no attribute '__version__'
- <get_version_using_pkgresources>: Invalid version number: None
- <get_builtin_module_version>: SUCCESS: 3.7.3.final.0
See the documentation for details. I copied the above details about the problem from this page.