At some point in a Python script, you may want to compare macOS versions (or, really, any software versions) to each other.
Back in the day, you could use Python’s LooseVersion
from distutils.version
, but that’s now deprecated:
>>> from distutils.version import LooseVersion
>>> LooseVersion('14.0.0') > LooseVersion('14.0')
True
>>> LooseVersion('14.0.0') == LooseVersion('14.0')
False
>>> LooseVersion('14.0') > LooseVersion('13.5.2')
True
>>> LooseVersion('13.4.1 (c)') > LooseVersion('13.4.1 (a)')
True
The non-deprecated Version
can run into issues, though, for Rapid Security Responses (thanks to @elios on the MacAdmins Slack for pointing this out):
>>> from packaging.version import Version
>>> Version('14.0.0') > Version('14.0')
False
>>> Version('14.0.0') == Version('14.0')
True
>>> Version('14.0') > Version('13.5.2')
True
>>> Version('13.4.1 (c)') > Version('13.4.1 (a)')
Traceback (most recent call last):
File "<stdin>", line 1, in
File "/Library/ManagedFrameworks/Python/Python3.framework/Versions/3.11/lib/python3.11/site-packages/packaging/version.py", line 197, in __init__
raise InvalidVersion(f"Invalid version: '{version}'")
packaging.version.InvalidVersion: Invalid version: '13.4.1 (c)'
If you have Munki available, Munki’s MunkiLooseVersion
works:
>>> import sys
>>> sys.path.insert(0, '/usr/local/munki')
>>> from munkilib.pkgutils import MunkiLooseVersion
>>> MunkiLooseVersion('14.0.0') > MunkiLooseVersion('14.0')
False
>>> MunkiLooseVersion('14.0.0') == MunkiLooseVersion('14.0')
True
>>> MunkiLooseVersion('14.0') > MunkiLooseVersion('13.5.2')
True
>>> MunkiLooseVersion('13.4.1 (c)') > MunkiLooseVersion('13.4.1 (a)')
True
I would still recommend MunkiLooseVersion
if you have it available, as it can handle some fairly complex versioning (even beyond macOS versions).
If you don’t have Munki available, Python’s own built-in comparisons (at least for macOS versions) oddly seem to work better than Version
from packaging.version
:
>>> '14.0.0' > '14.0'
True
>>> '14.0.0' == '14.0'
False
>>> '14.0' > '13.5.2'
True
>>> '13.4.1 (c)' > '13.4.1 (a)'
True
Leave a Reply