Comparing macOS versions using Python

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


Posted

in

by

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *