I need to ensure that one of the imported packages is at least v1.2.6. All the questions I have seen on here check the version of Python running. I would like to check the version of the module.
My current solution is messy. There must be a pythonic solution to this.
import pypfopt
ver = pypfopt.__version__
major, minor, iter = ver.split('.')
major = int(major)
minor = int(minor)
iter = int(iter)
if major < 1:
logger.error("major version less than 1")
if minor < 2:
logger.error("minor version less than 2")
if iter < 6:
logger.error("iter version less than 6")
While there are similar questions on SO, 1, 2, 3, these are addressing how to get and print the result from module.__version__
, which I am already doing.
My question, is whether there is a clean, pythonic way to check that version number against the minimum version number. eg:
if pypfopt.__version__ < 1.2.6:
logger.error("Version is too low. Update")
but __version__
returns a string, and since there are two decimals (1.2.6) it can't be converted to a float, and then compared. Currently, I am converting each individual number to an int, and then doing comparisons.
You can use packaging
module. Install it with pip install packaging
and then:
from packaging import version
import pypfopt
ver = pypfopt.__version__
if version.parse(ver) < version.parse('1.2.6'):
logger.error('Version is too low. Update')
pkg_resources
, distributed with setuptools
, does what you need and handles situations where package.__version__
doesn't exist.
Here is how you'd require a minimal version of pypfopt==1.2.6
in your example:
python -c 'import pkg_resources; pkg_resources.require("pypfopt>=1.2.6")'
I don't have this package installed so I get:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "python3.8/site-packages/pkg_resources/__init__.py", line 884, in require
needed = self.resolve(parse_requirements(requirements))
File "python3.8/site-packages/pkg_resources/__init__.py", line 770, in resolve
raise DistributionNotFound(req, requirers)
pkg_resources.DistributionNotFound: The 'pypfopt>=1.2.6' distribution was not found
and is required by the application
caveat: I used it a lot until now that I have encountered a problem where the package in question has the right version, but its dependencies are not met, and so pkg_resources
reports a failure.
For example: I have pytorch_lightning==1.0.5
installed, but I installed a new version for one of its dependencies that it doesn't list as supported. I was expecting the following to pass, but it fails:
python -c 'import pkg_resources; pkg_resources.require("pytorch_lightning>=1.0.4")'
with:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "python3.8/site-packages/pkg_resources/__init__.py", line 884, in require
needed = self.resolve(parse_requirements(requirements))
File "python3.8/site-packages/pkg_resources/__init__.py", line 775, in resolve
raise VersionConflict(dist, req).with_context(dependent_req)
pkg_resources.ContextualVersionConflict:
(torch 1.8.0.dev20201106+cu110 (python3.8/site-packages),
Requirement.parse('torch<1.8,>=1.3'), {'pytorch-lightning'})
which is the right thing to do if you want to ensure that not only the desired module is there and has the correct version, but that its dependencies are correct too.
So I'm signalling here, that pkg_resources
does more than comparing the version number of the installed package - it also checks its dependencies. Which may or may not meet your needs.
And here is the version that doesn't check whether the dependencies are OK. In it we use pkg_resources
to just get the package's version, and delegate the comparison to packaging
as described in various answers on SO:
import pkg_resources
from packaging import version
pkg = "pytorch_lightning"
min_ver = "1.0.4"
got_ver = pkg_resources.get_distribution("pytorch_lightning").version
if version.parse(got_ver) < version.parse(min_ver):
raise pkg_resources.VersionConflict(f"{pkg}>={min_ver} is needed, but found {pkg}=={got_ver}")
This time despite the dependencies being incorrect (in my example), it's sufficient that the version number is high enough, so the script can go ahead and use pytorch_lightning
(I validated that it works just fine with newer versions of its dependencies).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With