diff --git a/lib/spack/spack/test/versions.py b/lib/spack/spack/test/versions.py index 4624f901c8ba8ad71f68c56606fa7624a01565e7..a3a328fb14e55c341e671e65d3f3e9d406032354 100644 --- a/lib/spack/spack/test/versions.py +++ b/lib/spack/spack/test/versions.py @@ -389,3 +389,39 @@ def test_formatted_strings(self): self.assertEqual(v.dotted, '1.2.3') self.assertEqual(v.dashed, '1-2-3') self.assertEqual(v.underscored, '1_2_3') + + def test_repr_and_str(self): + + def check_repr_and_str(vrs): + a = Version(vrs) + self.assertEqual(repr(a), 'Version(\'' + vrs + '\')') + b = eval(repr(a)) + self.assertEqual(a, b) + self.assertEqual(str(a), vrs) + self.assertEqual(str(a), str(b)) + + check_repr_and_str('1.2.3') + check_repr_and_str('R2016a') + check_repr_and_str('R2016a.2-3_4') + + def test_get_item(self): + a = Version('0.1_2-3') + self.assertTrue(isinstance(a[1], int)) + # Test slicing + b = a[0:2] + self.assertTrue(isinstance(b, Version)) + self.assertEqual(b, Version('0.1')) + self.assertEqual(repr(b), 'Version(\'0.1\')') + self.assertEqual(str(b), '0.1') + b = a[0:3] + self.assertTrue(isinstance(b, Version)) + self.assertEqual(b, Version('0.1_2')) + self.assertEqual(repr(b), 'Version(\'0.1_2\')') + self.assertEqual(str(b), '0.1_2') + b = a[1:] + self.assertTrue(isinstance(b, Version)) + self.assertEqual(b, Version('1_2-3')) + self.assertEqual(repr(b), 'Version(\'1_2-3\')') + self.assertEqual(str(b), '1_2-3') + # Raise TypeError on tuples + self.assertRaises(TypeError, b.__getitem__, 1, 2) diff --git a/lib/spack/spack/version.py b/lib/spack/spack/version.py index 858d5814728d8a8e5e2e0e0ac2099fe48573d27b..683964394175e87b1a2a946ba2d97500405f15d0 100644 --- a/lib/spack/spack/version.py +++ b/lib/spack/spack/version.py @@ -44,6 +44,7 @@ concrete """ import re +import numbers from bisect import bisect_left from functools import wraps @@ -194,10 +195,24 @@ def __iter__(self): return iter(self.version) def __getitem__(self, idx): - return tuple(self.version[idx]) + cls = type(self) + if isinstance(idx, numbers.Integral): + return self.version[idx] + elif isinstance(idx, slice): + # Currently len(self.separators) == len(self.version) - 1 + extendend_separators = self.separators + ('',) + string_arg = [] + for token, sep in zip(self.version, extendend_separators)[idx]: + string_arg.append(str(token)) + string_arg.append(str(sep)) + string_arg.pop() # We don't need the last separator + string_arg = ''.join(string_arg) + return cls(string_arg) + message = '{cls.__name__} indices must be integers' + raise TypeError(message.format(cls=cls)) def __repr__(self): - return self.string + return 'Version(' + repr(self.string) + ')' def __str__(self): return self.string