Attachment 'lch.version.py'
Download 1 import itertools
2
3 fields = []
4 accumulator = []
5 fieldType = None
6
7
8 def endField():
9 global accumulator
10 global fields
11 global fieldType
12 stringMap = { "alpha" : -30, "beta" : -20, "rc" : -10, "final" : None }
13 if accumulator:
14 s = "".join(accumulator)
15 if s in stringMap:
16 value = stringMap[s]
17 if value is not None:
18 fields.append(value)
19 elif fieldType == 'ascii':
20 fields.extend([ord(c.upper()) for c in accumulator])
21 else:
22 assert fieldType == 'digits'
23 while len(accumulator) > 1 and accumulator[0] == '0':
24 accumulator.pop(0)
25 fields.append(int(s))
26 accumulator = []
27 fieldType = None
28
29
30
31 def split_version(s):
32 """Splits a version string into a tuple of integers."""
33
34 global accumulator
35 global fields
36 global fieldType
37
38 fields = []
39
40 for c in s:
41 if c.isdigit():
42 if fieldType == 'ascii':
43 endField()
44 fieldType = 'digits'
45 accumulator.append(c)
46 continue
47 if c.isalpha():
48 if fieldType == 'digits':
49 endField()
50 fieldType = 'ascii'
51 accumulator.append(c)
52 continue
53 endField()
54 endField()
55 while fields and (fields[-1] == 0):
56 fields.pop()
57 return tuple(fields)
58
59 def _split_nonfinal(v):
60 for i, field in enumerate(v):
61 if field < 0:
62 return v[:i], v[i:]
63 return v, ()
64
65 def compare_version_tuples(a, b):
66 """Compares two version tuples.
67
68 Returns 0 if they are equivalent,
69 a negative number if the first version is less than the second version,
70 and a positive number if the first version is greater than the second version.
71 """
72 a, aBeta = _split_nonfinal(a)
73 b, bBeta = _split_nonfinal(b)
74 for fa, fb in itertools.chain(itertools.izip_longest(a, b, fillvalue=0), itertools.izip_longest(aBeta, bBeta, fillvalue=0)):
75 if fa == fb:
76 continue
77 return 1 if (fa > fb) else -1
78 return 0
79
80 def is_final(a):
81 """Returns true if this is a 'final' version.
82 Returns false if it is not a 'final' version (an alpha, beta, rc)."""
83 for field in a:
84 if field < 0:
85 return False
86 return True
87
88 if __name__ == "__main__":
89 for s, version in (
90 ("1.2", (1, 2)),
91 ("1.2.0", (1, 2)),
92 ("1.0alpha1", (1, 0, -30, 1)),
93 ("1.0 alpha 1", (1, 0, -30, 1)),
94 ("1-0pa3", (1, 0, ord('p'.upper()), ord('a'.upper()), 3)),
95 ("1.003", (1, 3)),
96 ("1.3", (1, 3)),
97 ):
98 assert split_version(s) == version
99
100 for s in """
101 1.0 1.0 0
102 1.0 1 0
103 1.0 1.0.0.0 0
104 1.0 1.2 -1
105 1.2.0 1 1
106 1.0alpha1 1.0 -1
107 1.0alpha 1.0beta -1
108 1-0p3 1-0p4 -1
109 1.003 1.4 -1
110 1.0.0.0 1alpha3 1
111 """.strip().split("\n"):
112 v1, v2, expected = s.split()[:3]
113 expected = int(expected)
114 result = compare_version_tuples(split_version(v1), split_version(v2))
115 assert result == expected
Attached Files
To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.You are not allowed to attach a file to this page.