diff options
Diffstat (limited to 'venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/version.py')
| -rw-r--r-- | venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/version.py | 441 |
1 files changed, 0 insertions, 441 deletions
diff --git a/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/version.py b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/version.py deleted file mode 100644 index a8affbd..0000000 --- a/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/version.py +++ /dev/null | |||
| @@ -1,441 +0,0 @@ | |||
| 1 | # This file is dual licensed under the terms of the Apache License, Version | ||
| 2 | # 2.0, and the BSD License. See the LICENSE file in the root of this repository | ||
| 3 | # for complete details. | ||
| 4 | from __future__ import absolute_import, division, print_function | ||
| 5 | |||
| 6 | import collections | ||
| 7 | import itertools | ||
| 8 | import re | ||
| 9 | |||
| 10 | from ._structures import Infinity | ||
| 11 | |||
| 12 | |||
| 13 | __all__ = [ | ||
| 14 | "parse", "Version", "LegacyVersion", "InvalidVersion", "VERSION_PATTERN" | ||
| 15 | ] | ||
| 16 | |||
| 17 | |||
| 18 | _Version = collections.namedtuple( | ||
| 19 | "_Version", | ||
| 20 | ["epoch", "release", "dev", "pre", "post", "local"], | ||
| 21 | ) | ||
| 22 | |||
| 23 | |||
| 24 | def parse(version): | ||
| 25 | """ | ||
| 26 | Parse the given version string and return either a :class:`Version` object | ||
| 27 | or a :class:`LegacyVersion` object depending on if the given version is | ||
| 28 | a valid PEP 440 version or a legacy version. | ||
| 29 | """ | ||
| 30 | try: | ||
| 31 | return Version(version) | ||
| 32 | except InvalidVersion: | ||
| 33 | return LegacyVersion(version) | ||
| 34 | |||
| 35 | |||
| 36 | class InvalidVersion(ValueError): | ||
| 37 | """ | ||
| 38 | An invalid version was found, users should refer to PEP 440. | ||
| 39 | """ | ||
| 40 | |||
| 41 | |||
| 42 | class _BaseVersion(object): | ||
| 43 | |||
| 44 | def __hash__(self): | ||
| 45 | return hash(self._key) | ||
| 46 | |||
| 47 | def __lt__(self, other): | ||
| 48 | return self._compare(other, lambda s, o: s < o) | ||
| 49 | |||
| 50 | def __le__(self, other): | ||
| 51 | return self._compare(other, lambda s, o: s <= o) | ||
| 52 | |||
| 53 | def __eq__(self, other): | ||
| 54 | return self._compare(other, lambda s, o: s == o) | ||
| 55 | |||
| 56 | def __ge__(self, other): | ||
| 57 | return self._compare(other, lambda s, o: s >= o) | ||
| 58 | |||
| 59 | def __gt__(self, other): | ||
| 60 | return self._compare(other, lambda s, o: s > o) | ||
| 61 | |||
| 62 | def __ne__(self, other): | ||
| 63 | return self._compare(other, lambda s, o: s != o) | ||
| 64 | |||
| 65 | def _compare(self, other, method): | ||
| 66 | if not isinstance(other, _BaseVersion): | ||
| 67 | return NotImplemented | ||
| 68 | |||
| 69 | return method(self._key, other._key) | ||
| 70 | |||
| 71 | |||
| 72 | class LegacyVersion(_BaseVersion): | ||
| 73 | |||
| 74 | def __init__(self, version): | ||
| 75 | self._version = str(version) | ||
| 76 | self._key = _legacy_cmpkey(self._version) | ||
| 77 | |||
| 78 | def __str__(self): | ||
| 79 | return self._version | ||
| 80 | |||
| 81 | def __repr__(self): | ||
| 82 | return "<LegacyVersion({0})>".format(repr(str(self))) | ||
| 83 | |||
| 84 | @property | ||
| 85 | def public(self): | ||
| 86 | return self._version | ||
| 87 | |||
| 88 | @property | ||
| 89 | def base_version(self): | ||
| 90 | return self._version | ||
| 91 | |||
| 92 | @property | ||
| 93 | def epoch(self): | ||
| 94 | return -1 | ||
| 95 | |||
| 96 | @property | ||
| 97 | def release(self): | ||
| 98 | return None | ||
| 99 | |||
| 100 | @property | ||
| 101 | def pre(self): | ||
| 102 | return None | ||
| 103 | |||
| 104 | @property | ||
| 105 | def post(self): | ||
| 106 | return None | ||
| 107 | |||
| 108 | @property | ||
| 109 | def dev(self): | ||
| 110 | return None | ||
| 111 | |||
| 112 | @property | ||
| 113 | def local(self): | ||
| 114 | return None | ||
| 115 | |||
| 116 | @property | ||
| 117 | def is_prerelease(self): | ||
| 118 | return False | ||
| 119 | |||
| 120 | @property | ||
| 121 | def is_postrelease(self): | ||
| 122 | return False | ||
| 123 | |||
| 124 | @property | ||
| 125 | def is_devrelease(self): | ||
| 126 | return False | ||
| 127 | |||
| 128 | |||
| 129 | _legacy_version_component_re = re.compile( | ||
| 130 | r"(\d+ | [a-z]+ | \.| -)", re.VERBOSE, | ||
| 131 | ) | ||
| 132 | |||
| 133 | _legacy_version_replacement_map = { | ||
| 134 | "pre": "c", "preview": "c", "-": "final-", "rc": "c", "dev": "@", | ||
| 135 | } | ||
| 136 | |||
| 137 | |||
| 138 | def _parse_version_parts(s): | ||
| 139 | for part in _legacy_version_component_re.split(s): | ||
| 140 | part = _legacy_version_replacement_map.get(part, part) | ||
| 141 | |||
| 142 | if not part or part == ".": | ||
| 143 | continue | ||
| 144 | |||
| 145 | if part[:1] in "0123456789": | ||
| 146 | # pad for numeric comparison | ||
| 147 | yield part.zfill(8) | ||
| 148 | else: | ||
| 149 | yield "*" + part | ||
| 150 | |||
| 151 | # ensure that alpha/beta/candidate are before final | ||
| 152 | yield "*final" | ||
| 153 | |||
| 154 | |||
| 155 | def _legacy_cmpkey(version): | ||
| 156 | # We hardcode an epoch of -1 here. A PEP 440 version can only have a epoch | ||
| 157 | # greater than or equal to 0. This will effectively put the LegacyVersion, | ||
| 158 | # which uses the defacto standard originally implemented by setuptools, | ||
| 159 | # as before all PEP 440 versions. | ||
| 160 | epoch = -1 | ||
| 161 | |||
| 162 | # This scheme is taken from pkg_resources.parse_version setuptools prior to | ||
| 163 | # it's adoption of the packaging library. | ||
| 164 | parts = [] | ||
| 165 | for part in _parse_version_parts(version.lower()): | ||
| 166 | if part.startswith("*"): | ||
| 167 | # remove "-" before a prerelease tag | ||
| 168 | if part < "*final": | ||
| 169 | while parts and parts[-1] == "*final-": | ||
| 170 | parts.pop() | ||
| 171 | |||
| 172 | # remove trailing zeros from each series of numeric parts | ||
| 173 | while parts and parts[-1] == "00000000": | ||
| 174 | parts.pop() | ||
| 175 | |||
| 176 | parts.append(part) | ||
| 177 | parts = tuple(parts) | ||
| 178 | |||
| 179 | return epoch, parts | ||
| 180 | |||
| 181 | |||
| 182 | # Deliberately not anchored to the start and end of the string, to make it | ||
| 183 | # easier for 3rd party code to reuse | ||
| 184 | VERSION_PATTERN = r""" | ||
| 185 | v? | ||
| 186 | (?: | ||
| 187 | (?:(?P<epoch>[0-9]+)!)? # epoch | ||
| 188 | (?P<release>[0-9]+(?:\.[0-9]+)*) # release segment | ||
| 189 | (?P<pre> # pre-release | ||
| 190 | [-_\.]? | ||
| 191 | (?P<pre_l>(a|b|c|rc|alpha|beta|pre|preview)) | ||
| 192 | [-_\.]? | ||
| 193 | (?P<pre_n>[0-9]+)? | ||
| 194 | )? | ||
| 195 | (?P<post> # post release | ||
| 196 | (?:-(?P<post_n1>[0-9]+)) | ||
| 197 | | | ||
| 198 | (?: | ||
| 199 | [-_\.]? | ||
| 200 | (?P<post_l>post|rev|r) | ||
| 201 | [-_\.]? | ||
| 202 | (?P<post_n2>[0-9]+)? | ||
| 203 | ) | ||
| 204 | )? | ||
| 205 | (?P<dev> # dev release | ||
| 206 | [-_\.]? | ||
| 207 | (?P<dev_l>dev) | ||
| 208 | [-_\.]? | ||
| 209 | (?P<dev_n>[0-9]+)? | ||
| 210 | )? | ||
| 211 | ) | ||
| 212 | (?:\+(?P<local>[a-z0-9]+(?:[-_\.][a-z0-9]+)*))? # local version | ||
| 213 | """ | ||
| 214 | |||
| 215 | |||
| 216 | class Version(_BaseVersion): | ||
| 217 | |||
| 218 | _regex = re.compile( | ||
| 219 | r"^\s*" + VERSION_PATTERN + r"\s*$", | ||
| 220 | re.VERBOSE | re.IGNORECASE, | ||
| 221 | ) | ||
| 222 | |||
| 223 | def __init__(self, version): | ||
| 224 | # Validate the version and parse it into pieces | ||
| 225 | match = self._regex.search(version) | ||
| 226 | if not match: | ||
| 227 | raise InvalidVersion("Invalid version: '{0}'".format(version)) | ||
| 228 | |||
| 229 | # Store the parsed out pieces of the version | ||
| 230 | self._version = _Version( | ||
| 231 | epoch=int(match.group("epoch")) if match.group("epoch") else 0, | ||
| 232 | release=tuple(int(i) for i in match.group("release").split(".")), | ||
| 233 | pre=_parse_letter_version( | ||
| 234 | match.group("pre_l"), | ||
| 235 | match.group("pre_n"), | ||
| 236 | ), | ||
| 237 | post=_parse_letter_version( | ||
| 238 | match.group("post_l"), | ||
| 239 | match.group("post_n1") or match.group("post_n2"), | ||
| 240 | ), | ||
| 241 | dev=_parse_letter_version( | ||
| 242 | match.group("dev_l"), | ||
| 243 | match.group("dev_n"), | ||
| 244 | ), | ||
| 245 | local=_parse_local_version(match.group("local")), | ||
| 246 | ) | ||
| 247 | |||
| 248 | # Generate a key which will be used for sorting | ||
| 249 | self._key = _cmpkey( | ||
| 250 | self._version.epoch, | ||
| 251 | self._version.release, | ||
| 252 | self._version.pre, | ||
| 253 | self._version.post, | ||
| 254 | self._version.dev, | ||
| 255 | self._version.local, | ||
| 256 | ) | ||
| 257 | |||
| 258 | def __repr__(self): | ||
| 259 | return "<Version({0})>".format(repr(str(self))) | ||
| 260 | |||
| 261 | def __str__(self): | ||
| 262 | parts = [] | ||
| 263 | |||
| 264 | # Epoch | ||
| 265 | if self.epoch != 0: | ||
| 266 | parts.append("{0}!".format(self.epoch)) | ||
| 267 | |||
| 268 | # Release segment | ||
| 269 | parts.append(".".join(str(x) for x in self.release)) | ||
| 270 | |||
| 271 | # Pre-release | ||
| 272 | if self.pre is not None: | ||
| 273 | parts.append("".join(str(x) for x in self.pre)) | ||
| 274 | |||
| 275 | # Post-release | ||
| 276 | if self.post is not None: | ||
| 277 | parts.append(".post{0}".format(self.post)) | ||
| 278 | |||
| 279 | # Development release | ||
| 280 | if self.dev is not None: | ||
| 281 | parts.append(".dev{0}".format(self.dev)) | ||
| 282 | |||
| 283 | # Local version segment | ||
| 284 | if self.local is not None: | ||
| 285 | parts.append("+{0}".format(self.local)) | ||
| 286 | |||
| 287 | return "".join(parts) | ||
| 288 | |||
| 289 | @property | ||
| 290 | def epoch(self): | ||
| 291 | return self._version.epoch | ||
| 292 | |||
| 293 | @property | ||
| 294 | def release(self): | ||
| 295 | return self._version.release | ||
| 296 | |||
| 297 | @property | ||
| 298 | def pre(self): | ||
| 299 | return self._version.pre | ||
| 300 | |||
| 301 | @property | ||
| 302 | def post(self): | ||
| 303 | return self._version.post[1] if self._version.post else None | ||
| 304 | |||
| 305 | @property | ||
| 306 | def dev(self): | ||
| 307 | return self._version.dev[1] if self._version.dev else None | ||
| 308 | |||
| 309 | @property | ||
| 310 | def local(self): | ||
| 311 | if self._version.local: | ||
| 312 | return ".".join(str(x) for x in self._version.local) | ||
| 313 | else: | ||
| 314 | return None | ||
| 315 | |||
| 316 | @property | ||
| 317 | def public(self): | ||
| 318 | return str(self).split("+", 1)[0] | ||
| 319 | |||
| 320 | @property | ||
| 321 | def base_version(self): | ||
| 322 | parts = [] | ||
| 323 | |||
| 324 | # Epoch | ||
| 325 | if self.epoch != 0: | ||
| 326 | parts.append("{0}!".format(self.epoch)) | ||
| 327 | |||
| 328 | # Release segment | ||
| 329 | parts.append(".".join(str(x) for x in self.release)) | ||
| 330 | |||
| 331 | return "".join(parts) | ||
| 332 | |||
| 333 | @property | ||
| 334 | def is_prerelease(self): | ||
| 335 | return self.dev is not None or self.pre is not None | ||
| 336 | |||
| 337 | @property | ||
| 338 | def is_postrelease(self): | ||
| 339 | return self.post is not None | ||
| 340 | |||
| 341 | @property | ||
| 342 | def is_devrelease(self): | ||
| 343 | return self.dev is not None | ||
| 344 | |||
| 345 | |||
| 346 | def _parse_letter_version(letter, number): | ||
| 347 | if letter: | ||
| 348 | # We consider there to be an implicit 0 in a pre-release if there is | ||
| 349 | # not a numeral associated with it. | ||
| 350 | if number is None: | ||
| 351 | number = 0 | ||
| 352 | |||
| 353 | # We normalize any letters to their lower case form | ||
| 354 | letter = letter.lower() | ||
| 355 | |||
| 356 | # We consider some words to be alternate spellings of other words and | ||
| 357 | # in those cases we want to normalize the spellings to our preferred | ||
| 358 | # spelling. | ||
| 359 | if letter == "alpha": | ||
| 360 | letter = "a" | ||
| 361 | elif letter == "beta": | ||
| 362 | letter = "b" | ||
| 363 | elif letter in ["c", "pre", "preview"]: | ||
| 364 | letter = "rc" | ||
| 365 | elif letter in ["rev", "r"]: | ||
| 366 | letter = "post" | ||
| 367 | |||
| 368 | return letter, int(number) | ||
| 369 | if not letter and number: | ||
| 370 | # We assume if we are given a number, but we are not given a letter | ||
| 371 | # then this is using the implicit post release syntax (e.g. 1.0-1) | ||
| 372 | letter = "post" | ||
| 373 | |||
| 374 | return letter, int(number) | ||
| 375 | |||
| 376 | |||
| 377 | _local_version_separators = re.compile(r"[\._-]") | ||
| 378 | |||
| 379 | |||
| 380 | def _parse_local_version(local): | ||
| 381 | """ | ||
| 382 | Takes a string like abc.1.twelve and turns it into ("abc", 1, "twelve"). | ||
| 383 | """ | ||
| 384 | if local is not None: | ||
| 385 | return tuple( | ||
| 386 | part.lower() if not part.isdigit() else int(part) | ||
| 387 | for part in _local_version_separators.split(local) | ||
| 388 | ) | ||
| 389 | |||
| 390 | |||
| 391 | def _cmpkey(epoch, release, pre, post, dev, local): | ||
| 392 | # When we compare a release version, we want to compare it with all of the | ||
| 393 | # trailing zeros removed. So we'll use a reverse the list, drop all the now | ||
| 394 | # leading zeros until we come to something non zero, then take the rest | ||
| 395 | # re-reverse it back into the correct order and make it a tuple and use | ||
| 396 | # that for our sorting key. | ||
| 397 | release = tuple( | ||
| 398 | reversed(list( | ||
| 399 | itertools.dropwhile( | ||
| 400 | lambda x: x == 0, | ||
| 401 | reversed(release), | ||
| 402 | ) | ||
| 403 | )) | ||
| 404 | ) | ||
| 405 | |||
| 406 | # We need to "trick" the sorting algorithm to put 1.0.dev0 before 1.0a0. | ||
| 407 | # We'll do this by abusing the pre segment, but we _only_ want to do this | ||
| 408 | # if there is not a pre or a post segment. If we have one of those then | ||
| 409 | # the normal sorting rules will handle this case correctly. | ||
| 410 | if pre is None and post is None and dev is not None: | ||
| 411 | pre = -Infinity | ||
| 412 | # Versions without a pre-release (except as noted above) should sort after | ||
| 413 | # those with one. | ||
| 414 | elif pre is None: | ||
| 415 | pre = Infinity | ||
| 416 | |||
| 417 | # Versions without a post segment should sort before those with one. | ||
| 418 | if post is None: | ||
| 419 | post = -Infinity | ||
| 420 | |||
| 421 | # Versions without a development segment should sort after those with one. | ||
| 422 | if dev is None: | ||
| 423 | dev = Infinity | ||
| 424 | |||
| 425 | if local is None: | ||
| 426 | # Versions without a local segment should sort before those with one. | ||
| 427 | local = -Infinity | ||
| 428 | else: | ||
| 429 | # Versions with a local segment need that segment parsed to implement | ||
| 430 | # the sorting rules in PEP440. | ||
| 431 | # - Alpha numeric segments sort before numeric segments | ||
| 432 | # - Alpha numeric segments sort lexicographically | ||
| 433 | # - Numeric segments sort numerically | ||
| 434 | # - Shorter versions sort before longer versions when the prefixes | ||
| 435 | # match exactly | ||
| 436 | local = tuple( | ||
| 437 | (i, "") if isinstance(i, int) else (-Infinity, i) | ||
| 438 | for i in local | ||
| 439 | ) | ||
| 440 | |||
| 441 | return epoch, release, pre, post, dev, local | ||
