]> git.proxmox.com Git - mirror_edk2.git/blame - AppPkg/Applications/Python/Python-2.7.2/Lib/distutils/versionpredicate.py
EmbeddedPkg: Extend NvVarStoreFormattedLib LIBRARY_CLASS
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.2 / Lib / distutils / versionpredicate.py
CommitLineData
4710c53d 1"""Module for parsing and testing package version predicate strings.\r
2"""\r
3import re\r
4import distutils.version\r
5import operator\r
6\r
7\r
8re_validPackage = re.compile(r"(?i)^\s*([a-z_]\w*(?:\.[a-z_]\w*)*)(.*)")\r
9# (package) (rest)\r
10\r
11re_paren = re.compile(r"^\s*\((.*)\)\s*$") # (list) inside of parentheses\r
12re_splitComparison = re.compile(r"^\s*(<=|>=|<|>|!=|==)\s*([^\s,]+)\s*$")\r
13# (comp) (version)\r
14\r
15\r
16def splitUp(pred):\r
17 """Parse a single version comparison.\r
18\r
19 Return (comparison string, StrictVersion)\r
20 """\r
21 res = re_splitComparison.match(pred)\r
22 if not res:\r
23 raise ValueError("bad package restriction syntax: %r" % pred)\r
24 comp, verStr = res.groups()\r
25 return (comp, distutils.version.StrictVersion(verStr))\r
26\r
27compmap = {"<": operator.lt, "<=": operator.le, "==": operator.eq,\r
28 ">": operator.gt, ">=": operator.ge, "!=": operator.ne}\r
29\r
30class VersionPredicate:\r
31 """Parse and test package version predicates.\r
32\r
33 >>> v = VersionPredicate('pyepat.abc (>1.0, <3333.3a1, !=1555.1b3)')\r
34\r
35 The `name` attribute provides the full dotted name that is given::\r
36\r
37 >>> v.name\r
38 'pyepat.abc'\r
39\r
40 The str() of a `VersionPredicate` provides a normalized\r
41 human-readable version of the expression::\r
42\r
43 >>> print v\r
44 pyepat.abc (> 1.0, < 3333.3a1, != 1555.1b3)\r
45\r
46 The `satisfied_by()` method can be used to determine with a given\r
47 version number is included in the set described by the version\r
48 restrictions::\r
49\r
50 >>> v.satisfied_by('1.1')\r
51 True\r
52 >>> v.satisfied_by('1.4')\r
53 True\r
54 >>> v.satisfied_by('1.0')\r
55 False\r
56 >>> v.satisfied_by('4444.4')\r
57 False\r
58 >>> v.satisfied_by('1555.1b3')\r
59 False\r
60\r
61 `VersionPredicate` is flexible in accepting extra whitespace::\r
62\r
63 >>> v = VersionPredicate(' pat( == 0.1 ) ')\r
64 >>> v.name\r
65 'pat'\r
66 >>> v.satisfied_by('0.1')\r
67 True\r
68 >>> v.satisfied_by('0.2')\r
69 False\r
70\r
71 If any version numbers passed in do not conform to the\r
72 restrictions of `StrictVersion`, a `ValueError` is raised::\r
73\r
74 >>> v = VersionPredicate('p1.p2.p3.p4(>=1.0, <=1.3a1, !=1.2zb3)')\r
75 Traceback (most recent call last):\r
76 ...\r
77 ValueError: invalid version number '1.2zb3'\r
78\r
79 It the module or package name given does not conform to what's\r
80 allowed as a legal module or package name, `ValueError` is\r
81 raised::\r
82\r
83 >>> v = VersionPredicate('foo-bar')\r
84 Traceback (most recent call last):\r
85 ...\r
86 ValueError: expected parenthesized list: '-bar'\r
87\r
88 >>> v = VersionPredicate('foo bar (12.21)')\r
89 Traceback (most recent call last):\r
90 ...\r
91 ValueError: expected parenthesized list: 'bar (12.21)'\r
92\r
93 """\r
94\r
95 def __init__(self, versionPredicateStr):\r
96 """Parse a version predicate string.\r
97 """\r
98 # Fields:\r
99 # name: package name\r
100 # pred: list of (comparison string, StrictVersion)\r
101\r
102 versionPredicateStr = versionPredicateStr.strip()\r
103 if not versionPredicateStr:\r
104 raise ValueError("empty package restriction")\r
105 match = re_validPackage.match(versionPredicateStr)\r
106 if not match:\r
107 raise ValueError("bad package name in %r" % versionPredicateStr)\r
108 self.name, paren = match.groups()\r
109 paren = paren.strip()\r
110 if paren:\r
111 match = re_paren.match(paren)\r
112 if not match:\r
113 raise ValueError("expected parenthesized list: %r" % paren)\r
114 str = match.groups()[0]\r
115 self.pred = [splitUp(aPred) for aPred in str.split(",")]\r
116 if not self.pred:\r
117 raise ValueError("empty parenthesized list in %r"\r
118 % versionPredicateStr)\r
119 else:\r
120 self.pred = []\r
121\r
122 def __str__(self):\r
123 if self.pred:\r
124 seq = [cond + " " + str(ver) for cond, ver in self.pred]\r
125 return self.name + " (" + ", ".join(seq) + ")"\r
126 else:\r
127 return self.name\r
128\r
129 def satisfied_by(self, version):\r
130 """True if version is compatible with all the predicates in self.\r
131 The parameter version must be acceptable to the StrictVersion\r
132 constructor. It may be either a string or StrictVersion.\r
133 """\r
134 for cond, ver in self.pred:\r
135 if not compmap[cond](version, ver):\r
136 return False\r
137 return True\r
138\r
139\r
140_provision_rx = None\r
141\r
142def split_provision(value):\r
143 """Return the name and optional version number of a provision.\r
144\r
145 The version number, if given, will be returned as a `StrictVersion`\r
146 instance, otherwise it will be `None`.\r
147\r
148 >>> split_provision('mypkg')\r
149 ('mypkg', None)\r
150 >>> split_provision(' mypkg( 1.2 ) ')\r
151 ('mypkg', StrictVersion ('1.2'))\r
152 """\r
153 global _provision_rx\r
154 if _provision_rx is None:\r
155 _provision_rx = re.compile(\r
156 "([a-zA-Z_]\w*(?:\.[a-zA-Z_]\w*)*)(?:\s*\(\s*([^)\s]+)\s*\))?$")\r
157 value = value.strip()\r
158 m = _provision_rx.match(value)\r
159 if not m:\r
160 raise ValueError("illegal provides specification: %r" % value)\r
161 ver = m.group(2) or None\r
162 if ver:\r
163 ver = distutils.version.StrictVersion(ver)\r
164 return m.group(1), ver\r