4

Given two version numbers and a comparison specifier:

def check_versions(ver1, specifier, ver2):
    # TODO

check_versions("1.2.3", ">=", "2.0.0") # Should return True
check_versions("1.2.3", "==", "2.0.0") # Should return False

I would like to apply the comparison to the two versions such that I get the expected output from above.

I've found that I can compare versions using LooseVersion from distutils.version like so:

LooseVersion("1.2.3") >= LooseVersion("2.0.0")

But how can I make the comparison itself depend on the passed in specifier?

I could use the solution from here:

def check_versions(ver1, specifier, ver2):
    return {
        '==': LooseVersion(ver1) == LooseVersion(ver2),
        '>=': LooseVersion(ver1) >= LooseVersion(ver2),
        '<=': LooseVersion(ver1) <= LooseVersion(ver2),
        '>': LooseVersion(ver1) > LooseVersion(ver2),
        '<': LooseVersion(ver1) < LooseVersion(ver2),
    }.get(x, False)

But that just feels really clunky to me. Is there not a more elegant solution?

Community
  • 1
  • 1
Cory Klein
  • 51,188
  • 43
  • 183
  • 243

1 Answers1

9

Instead of creating a dictionary with all possible comparisons for the versions, you can just create a lookup for the used operators, e.g:

import operator as op
from distutils.version import LooseVersion

lookup = {'<': op.lt, '<=': op.le, '==': op.eq, '>=': op.ge, '>': op.gt}

def check_versions(ver1, specifier, ver2):
    try:
        return lookup[specifier](LooseVersion(ver1), LooseVersion(ver2))
    except KeyError:
        # unknown specifier
        return False
mata
  • 67,110
  • 10
  • 163
  • 162