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 - VersionMetadata field as indicated by PEP345, that is located:
 - 
- for built wheels distributions (PEP427), on the dist-infodirectory, but also in the dist-info folder name
- for built eggs distributions (legacy format from setuptools), on the egg-infodirectory, 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.