Skip to content

Commit e1ae67f

Browse files
committed
make LooseVersion('1.0') == LooseVersion('1')
Remove the pitfall where missing components were filled with empty strings that are less than any other value. The common expectation is that trailing zeroes are equal to zeroes. If the trailing part is a string the current behavior is kept.
1 parent 35ae0c2 commit e1ae67f

File tree

2 files changed

+28
-17
lines changed

2 files changed

+28
-17
lines changed

easybuild/tools/loose_version.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,17 +77,19 @@ def _cmp(self, other):
7777
if isinstance(other, str):
7878
other = LooseVersion(other)
7979

80-
# Modified: Behave the same in Python 2 & 3 when parts are of different types
81-
# Taken from https://bugs.python.org/issue14894
82-
for i, j in zip_longest(self.version, other.version, fillvalue=''):
83-
if not type(i) is type(j):
80+
# Modified: Use string comparison for different types and fill with zeroes/empty strings
81+
# Based on https://bugs.python.org/issue14894
82+
for i, j in zip_longest(self.version, other.version):
83+
if i is None:
84+
i = 0 if isinstance(j, int) else ''
85+
elif j is None:
86+
j = 0 if isinstance(i, int) else ''
87+
elif not type(i) is type(j):
8488
i = str(i)
8589
j = str(j)
86-
if i == j:
87-
continue
88-
elif i < j:
90+
if i < j:
8991
return -1
90-
else: # i > j
92+
if i > j:
9193
return 1
9294
return 0
9395

test/framework/utilities_test.py

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -140,15 +140,19 @@ def test_LooseVersion(self):
140140
self.assertLess(LooseVersion('2.1.5'), LooseVersion('2.2'))
141141
self.assertLess(LooseVersion('2.1.3'), LooseVersion('3'))
142142
self.assertLessEqual(LooseVersion('2.1.0'), LooseVersion('2.2'))
143-
# Careful here: 1.0 > 1 !!!
144-
self.assertGreater(LooseVersion('1.0'), LooseVersion('1'))
145-
self.assertLess(LooseVersion('1'), LooseVersion('1.0'))
143+
# Missing components are either empty strings or zeroes
144+
self.assertEqual(LooseVersion('1.0'), LooseVersion('1'))
145+
self.assertEqual(LooseVersion('1'), LooseVersion('1.0'))
146+
self.assertEqual(LooseVersion('1.0'), LooseVersion('1.'))
147+
self.assertGreater(LooseVersion('2.1.a'), LooseVersion('2.1'))
148+
self.assertGreater(LooseVersion('2.a'), LooseVersion('2'))
149+
146150
# checking prereleases
147151
self.assertGreater(LooseVersion('4.0.0-beta'), LooseVersion('4.0.0'))
148-
self.assertEqual(LooseVersion('4.0.0-beta').is_prerelease('4.0.0', ['-beta']), True)
149-
self.assertEqual(LooseVersion('4.0.0-beta').is_prerelease('4.0.0', ['rc']), False)
152+
self.assertTrue(LooseVersion('4.0.0-beta').is_prerelease('4.0.0', ['-beta']))
153+
self.assertFalse(LooseVersion('4.0.0-beta').is_prerelease('4.0.0', ['rc']))
150154

151-
# The following test is taken from Python distutils tests
155+
# The following test is based on the Python distutils tests
152156
# licensed under the Python Software Foundation License Version 2
153157
versions = (('1.5.1', '1.5.2b2', -1),
154158
('161', '3.10a', 1),
@@ -158,16 +162,21 @@ def test_LooseVersion(self):
158162
('2g6', '11g', -1),
159163
('0.960923', '2.2beta29', -1),
160164
('1.13++', '5.5.kw', -1),
161-
# Added from https://bugs.python.org/issue14894
162165
('a.12.b.c', 'a.b.3', -1),
163-
('1.0', '1', 1),
164-
('1', '1.0', -1))
166+
('1.0', '1', 0),
167+
('1.a', '1', 1),
168+
)
165169

166170
for v1, v2, wanted in versions:
167171
res = LooseVersion(v1)._cmp(LooseVersion(v2))
168172
self.assertEqual(res, wanted,
169173
'cmp(%s, %s) should be %s, got %s' %
170174
(v1, v2, wanted, res))
175+
# Test the inverse
176+
res = LooseVersion(v2)._cmp(LooseVersion(v1))
177+
self.assertEqual(res, -wanted,
178+
'cmp(%s, %s) should be %s, got %s' %
179+
(v2, v1, -wanted, res))
171180
# vstring is the unparsed version
172181
self.assertEqual(LooseVersion(v1).vstring, v1)
173182

0 commit comments

Comments
 (0)