diff options
| author | Shubham Saini <shubham6405@gmail.com> | 2018-12-11 10:01:23 +0000 |
|---|---|---|
| committer | Shubham Saini <shubham6405@gmail.com> | 2018-12-11 10:01:23 +0000 |
| commit | 68df54d6629ec019142eb149dd037774f2d11e7c (patch) | |
| tree | 345bc22d46b4e01a4ba8303b94278952a4ed2b9e /venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging | |
First commit
Diffstat (limited to 'venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging')
9 files changed, 1844 insertions, 0 deletions
diff --git a/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__about__.py b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__about__.py new file mode 100644 index 0000000..bb79fb7 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__about__.py | |||
| @@ -0,0 +1,21 @@ | |||
| 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 | __all__ = [ | ||
| 7 | "__title__", "__summary__", "__uri__", "__version__", "__author__", | ||
| 8 | "__email__", "__license__", "__copyright__", | ||
| 9 | ] | ||
| 10 | |||
| 11 | __title__ = "packaging" | ||
| 12 | __summary__ = "Core utilities for Python packages" | ||
| 13 | __uri__ = "https://github.com/pypa/packaging" | ||
| 14 | |||
| 15 | __version__ = "17.1" | ||
| 16 | |||
| 17 | __author__ = "Donald Stufft and individual contributors" | ||
| 18 | __email__ = "donald@stufft.io" | ||
| 19 | |||
| 20 | __license__ = "BSD or Apache License, Version 2.0" | ||
| 21 | __copyright__ = "Copyright 2014-2016 %s" % __author__ | ||
diff --git a/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__init__.py b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__init__.py new file mode 100644 index 0000000..e520d35 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__init__.py | |||
| @@ -0,0 +1,14 @@ | |||
| 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 | from .__about__ import ( | ||
| 7 | __author__, __copyright__, __email__, __license__, __summary__, __title__, | ||
| 8 | __uri__, __version__ | ||
| 9 | ) | ||
| 10 | |||
| 11 | __all__ = [ | ||
| 12 | "__title__", "__summary__", "__uri__", "__version__", "__author__", | ||
| 13 | "__email__", "__license__", "__copyright__", | ||
| 14 | ] | ||
diff --git a/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/_compat.py b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/_compat.py new file mode 100644 index 0000000..6daa860 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/_compat.py | |||
| @@ -0,0 +1,30 @@ | |||
| 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 sys | ||
| 7 | |||
| 8 | |||
| 9 | PY2 = sys.version_info[0] == 2 | ||
| 10 | PY3 = sys.version_info[0] == 3 | ||
| 11 | |||
| 12 | # flake8: noqa | ||
| 13 | |||
| 14 | if PY3: | ||
| 15 | string_types = str, | ||
| 16 | else: | ||
| 17 | string_types = basestring, | ||
| 18 | |||
| 19 | |||
| 20 | def with_metaclass(meta, *bases): | ||
| 21 | """ | ||
| 22 | Create a base class with a metaclass. | ||
| 23 | """ | ||
| 24 | # This requires a bit of explanation: the basic idea is to make a dummy | ||
| 25 | # metaclass for one level of class instantiation that replaces itself with | ||
| 26 | # the actual metaclass. | ||
| 27 | class metaclass(meta): | ||
| 28 | def __new__(cls, name, this_bases, d): | ||
| 29 | return meta(name, bases, d) | ||
| 30 | return type.__new__(metaclass, 'temporary_class', (), {}) | ||
diff --git a/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/_structures.py b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/_structures.py new file mode 100644 index 0000000..3f0c27f --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/_structures.py | |||
| @@ -0,0 +1,70 @@ | |||
| 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 | |||
| 7 | class Infinity(object): | ||
| 8 | |||
| 9 | def __repr__(self): | ||
| 10 | return "Infinity" | ||
| 11 | |||
| 12 | def __hash__(self): | ||
| 13 | return hash(repr(self)) | ||
| 14 | |||
| 15 | def __lt__(self, other): | ||
| 16 | return False | ||
| 17 | |||
| 18 | def __le__(self, other): | ||
| 19 | return False | ||
| 20 | |||
| 21 | def __eq__(self, other): | ||
| 22 | return isinstance(other, self.__class__) | ||
| 23 | |||
| 24 | def __ne__(self, other): | ||
| 25 | return not isinstance(other, self.__class__) | ||
| 26 | |||
| 27 | def __gt__(self, other): | ||
| 28 | return True | ||
| 29 | |||
| 30 | def __ge__(self, other): | ||
| 31 | return True | ||
| 32 | |||
| 33 | def __neg__(self): | ||
| 34 | return NegativeInfinity | ||
| 35 | |||
| 36 | |||
| 37 | Infinity = Infinity() | ||
| 38 | |||
| 39 | |||
| 40 | class NegativeInfinity(object): | ||
| 41 | |||
| 42 | def __repr__(self): | ||
| 43 | return "-Infinity" | ||
| 44 | |||
| 45 | def __hash__(self): | ||
| 46 | return hash(repr(self)) | ||
| 47 | |||
| 48 | def __lt__(self, other): | ||
| 49 | return True | ||
| 50 | |||
| 51 | def __le__(self, other): | ||
| 52 | return True | ||
| 53 | |||
| 54 | def __eq__(self, other): | ||
| 55 | return isinstance(other, self.__class__) | ||
| 56 | |||
| 57 | def __ne__(self, other): | ||
| 58 | return not isinstance(other, self.__class__) | ||
| 59 | |||
| 60 | def __gt__(self, other): | ||
| 61 | return False | ||
| 62 | |||
| 63 | def __ge__(self, other): | ||
| 64 | return False | ||
| 65 | |||
| 66 | def __neg__(self): | ||
| 67 | return Infinity | ||
| 68 | |||
| 69 | |||
| 70 | NegativeInfinity = NegativeInfinity() | ||
diff --git a/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/markers.py b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/markers.py new file mode 100644 index 0000000..b4dc0b9 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/markers.py | |||
| @@ -0,0 +1,301 @@ | |||
| 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 operator | ||
| 7 | import os | ||
| 8 | import platform | ||
| 9 | import sys | ||
| 10 | |||
| 11 | from pip._vendor.pyparsing import ParseException, ParseResults, stringStart, stringEnd | ||
| 12 | from pip._vendor.pyparsing import ZeroOrMore, Group, Forward, QuotedString | ||
| 13 | from pip._vendor.pyparsing import Literal as L # noqa | ||
| 14 | |||
| 15 | from ._compat import string_types | ||
| 16 | from .specifiers import Specifier, InvalidSpecifier | ||
| 17 | |||
| 18 | |||
| 19 | __all__ = [ | ||
| 20 | "InvalidMarker", "UndefinedComparison", "UndefinedEnvironmentName", | ||
| 21 | "Marker", "default_environment", | ||
| 22 | ] | ||
| 23 | |||
| 24 | |||
| 25 | class InvalidMarker(ValueError): | ||
| 26 | """ | ||
| 27 | An invalid marker was found, users should refer to PEP 508. | ||
| 28 | """ | ||
| 29 | |||
| 30 | |||
| 31 | class UndefinedComparison(ValueError): | ||
| 32 | """ | ||
| 33 | An invalid operation was attempted on a value that doesn't support it. | ||
| 34 | """ | ||
| 35 | |||
| 36 | |||
| 37 | class UndefinedEnvironmentName(ValueError): | ||
| 38 | """ | ||
| 39 | A name was attempted to be used that does not exist inside of the | ||
| 40 | environment. | ||
| 41 | """ | ||
| 42 | |||
| 43 | |||
| 44 | class Node(object): | ||
| 45 | |||
| 46 | def __init__(self, value): | ||
| 47 | self.value = value | ||
| 48 | |||
| 49 | def __str__(self): | ||
| 50 | return str(self.value) | ||
| 51 | |||
| 52 | def __repr__(self): | ||
| 53 | return "<{0}({1!r})>".format(self.__class__.__name__, str(self)) | ||
| 54 | |||
| 55 | def serialize(self): | ||
| 56 | raise NotImplementedError | ||
| 57 | |||
| 58 | |||
| 59 | class Variable(Node): | ||
| 60 | |||
| 61 | def serialize(self): | ||
| 62 | return str(self) | ||
| 63 | |||
| 64 | |||
| 65 | class Value(Node): | ||
| 66 | |||
| 67 | def serialize(self): | ||
| 68 | return '"{0}"'.format(self) | ||
| 69 | |||
| 70 | |||
| 71 | class Op(Node): | ||
| 72 | |||
| 73 | def serialize(self): | ||
| 74 | return str(self) | ||
| 75 | |||
| 76 | |||
| 77 | VARIABLE = ( | ||
| 78 | L("implementation_version") | | ||
| 79 | L("platform_python_implementation") | | ||
| 80 | L("implementation_name") | | ||
| 81 | L("python_full_version") | | ||
| 82 | L("platform_release") | | ||
| 83 | L("platform_version") | | ||
| 84 | L("platform_machine") | | ||
| 85 | L("platform_system") | | ||
| 86 | L("python_version") | | ||
| 87 | L("sys_platform") | | ||
| 88 | L("os_name") | | ||
| 89 | L("os.name") | # PEP-345 | ||
| 90 | L("sys.platform") | # PEP-345 | ||
| 91 | L("platform.version") | # PEP-345 | ||
| 92 | L("platform.machine") | # PEP-345 | ||
| 93 | L("platform.python_implementation") | # PEP-345 | ||
| 94 | L("python_implementation") | # undocumented setuptools legacy | ||
| 95 | L("extra") | ||
| 96 | ) | ||
| 97 | ALIASES = { | ||
| 98 | 'os.name': 'os_name', | ||
| 99 | 'sys.platform': 'sys_platform', | ||
| 100 | 'platform.version': 'platform_version', | ||
| 101 | 'platform.machine': 'platform_machine', | ||
| 102 | 'platform.python_implementation': 'platform_python_implementation', | ||
| 103 | 'python_implementation': 'platform_python_implementation' | ||
| 104 | } | ||
| 105 | VARIABLE.setParseAction(lambda s, l, t: Variable(ALIASES.get(t[0], t[0]))) | ||
| 106 | |||
| 107 | VERSION_CMP = ( | ||
| 108 | L("===") | | ||
| 109 | L("==") | | ||
| 110 | L(">=") | | ||
| 111 | L("<=") | | ||
| 112 | L("!=") | | ||
| 113 | L("~=") | | ||
| 114 | L(">") | | ||
| 115 | L("<") | ||
| 116 | ) | ||
| 117 | |||
| 118 | MARKER_OP = VERSION_CMP | L("not in") | L("in") | ||
| 119 | MARKER_OP.setParseAction(lambda s, l, t: Op(t[0])) | ||
| 120 | |||
| 121 | MARKER_VALUE = QuotedString("'") | QuotedString('"') | ||
| 122 | MARKER_VALUE.setParseAction(lambda s, l, t: Value(t[0])) | ||
| 123 | |||
| 124 | BOOLOP = L("and") | L("or") | ||
| 125 | |||
| 126 | MARKER_VAR = VARIABLE | MARKER_VALUE | ||
| 127 | |||
| 128 | MARKER_ITEM = Group(MARKER_VAR + MARKER_OP + MARKER_VAR) | ||
| 129 | MARKER_ITEM.setParseAction(lambda s, l, t: tuple(t[0])) | ||
| 130 | |||
| 131 | LPAREN = L("(").suppress() | ||
| 132 | RPAREN = L(")").suppress() | ||
| 133 | |||
| 134 | MARKER_EXPR = Forward() | ||
| 135 | MARKER_ATOM = MARKER_ITEM | Group(LPAREN + MARKER_EXPR + RPAREN) | ||
| 136 | MARKER_EXPR << MARKER_ATOM + ZeroOrMore(BOOLOP + MARKER_EXPR) | ||
| 137 | |||
| 138 | MARKER = stringStart + MARKER_EXPR + stringEnd | ||
| 139 | |||
| 140 | |||
| 141 | def _coerce_parse_result(results): | ||
| 142 | if isinstance(results, ParseResults): | ||
| 143 | return [_coerce_parse_result(i) for i in results] | ||
| 144 | else: | ||
| 145 | return results | ||
| 146 | |||
| 147 | |||
| 148 | def _format_marker(marker, first=True): | ||
| 149 | assert isinstance(marker, (list, tuple, string_types)) | ||
| 150 | |||
| 151 | # Sometimes we have a structure like [[...]] which is a single item list | ||
| 152 | # where the single item is itself it's own list. In that case we want skip | ||
| 153 | # the rest of this function so that we don't get extraneous () on the | ||
| 154 | # outside. | ||
| 155 | if (isinstance(marker, list) and len(marker) == 1 and | ||
| 156 | isinstance(marker[0], (list, tuple))): | ||
| 157 | return _format_marker(marker[0]) | ||
| 158 | |||
| 159 | if isinstance(marker, list): | ||
| 160 | inner = (_format_marker(m, first=False) for m in marker) | ||
| 161 | if first: | ||
| 162 | return " ".join(inner) | ||
| 163 | else: | ||
| 164 | return "(" + " ".join(inner) + ")" | ||
| 165 | elif isinstance(marker, tuple): | ||
| 166 | return " ".join([m.serialize() for m in marker]) | ||
| 167 | else: | ||
| 168 | return marker | ||
| 169 | |||
| 170 | |||
| 171 | _operators = { | ||
| 172 | "in": lambda lhs, rhs: lhs in rhs, | ||
| 173 | "not in": lambda lhs, rhs: lhs not in rhs, | ||
| 174 | "<": operator.lt, | ||
| 175 | "<=": operator.le, | ||
| 176 | "==": operator.eq, | ||
| 177 | "!=": operator.ne, | ||
| 178 | ">=": operator.ge, | ||
| 179 | ">": operator.gt, | ||
| 180 | } | ||
| 181 | |||
| 182 | |||
| 183 | def _eval_op(lhs, op, rhs): | ||
| 184 | try: | ||
| 185 | spec = Specifier("".join([op.serialize(), rhs])) | ||
| 186 | except InvalidSpecifier: | ||
| 187 | pass | ||
| 188 | else: | ||
| 189 | return spec.contains(lhs) | ||
| 190 | |||
| 191 | oper = _operators.get(op.serialize()) | ||
| 192 | if oper is None: | ||
| 193 | raise UndefinedComparison( | ||
| 194 | "Undefined {0!r} on {1!r} and {2!r}.".format(op, lhs, rhs) | ||
| 195 | ) | ||
| 196 | |||
| 197 | return oper(lhs, rhs) | ||
| 198 | |||
| 199 | |||
| 200 | _undefined = object() | ||
| 201 | |||
| 202 | |||
| 203 | def _get_env(environment, name): | ||
| 204 | value = environment.get(name, _undefined) | ||
| 205 | |||
| 206 | if value is _undefined: | ||
| 207 | raise UndefinedEnvironmentName( | ||
| 208 | "{0!r} does not exist in evaluation environment.".format(name) | ||
| 209 | ) | ||
| 210 | |||
| 211 | return value | ||
| 212 | |||
| 213 | |||
| 214 | def _evaluate_markers(markers, environment): | ||
| 215 | groups = [[]] | ||
| 216 | |||
| 217 | for marker in markers: | ||
| 218 | assert isinstance(marker, (list, tuple, string_types)) | ||
| 219 | |||
| 220 | if isinstance(marker, list): | ||
| 221 | groups[-1].append(_evaluate_markers(marker, environment)) | ||
| 222 | elif isinstance(marker, tuple): | ||
| 223 | lhs, op, rhs = marker | ||
| 224 | |||
| 225 | if isinstance(lhs, Variable): | ||
| 226 | lhs_value = _get_env(environment, lhs.value) | ||
| 227 | rhs_value = rhs.value | ||
| 228 | else: | ||
| 229 | lhs_value = lhs.value | ||
| 230 | rhs_value = _get_env(environment, rhs.value) | ||
| 231 | |||
| 232 | groups[-1].append(_eval_op(lhs_value, op, rhs_value)) | ||
| 233 | else: | ||
| 234 | assert marker in ["and", "or"] | ||
| 235 | if marker == "or": | ||
| 236 | groups.append([]) | ||
| 237 | |||
| 238 | return any(all(item) for item in groups) | ||
| 239 | |||
| 240 | |||
| 241 | def format_full_version(info): | ||
| 242 | version = '{0.major}.{0.minor}.{0.micro}'.format(info) | ||
| 243 | kind = info.releaselevel | ||
| 244 | if kind != 'final': | ||
| 245 | version += kind[0] + str(info.serial) | ||
| 246 | return version | ||
| 247 | |||
| 248 | |||
| 249 | def default_environment(): | ||
| 250 | if hasattr(sys, 'implementation'): | ||
| 251 | iver = format_full_version(sys.implementation.version) | ||
| 252 | implementation_name = sys.implementation.name | ||
| 253 | else: | ||
| 254 | iver = '0' | ||
| 255 | implementation_name = '' | ||
| 256 | |||
| 257 | return { | ||
| 258 | "implementation_name": implementation_name, | ||
| 259 | "implementation_version": iver, | ||
| 260 | "os_name": os.name, | ||
| 261 | "platform_machine": platform.machine(), | ||
| 262 | "platform_release": platform.release(), | ||
| 263 | "platform_system": platform.system(), | ||
| 264 | "platform_version": platform.version(), | ||
| 265 | "python_full_version": platform.python_version(), | ||
| 266 | "platform_python_implementation": platform.python_implementation(), | ||
| 267 | "python_version": platform.python_version()[:3], | ||
| 268 | "sys_platform": sys.platform, | ||
| 269 | } | ||
| 270 | |||
| 271 | |||
| 272 | class Marker(object): | ||
| 273 | |||
| 274 | def __init__(self, marker): | ||
| 275 | try: | ||
| 276 | self._markers = _coerce_parse_result(MARKER.parseString(marker)) | ||
| 277 | except ParseException as e: | ||
| 278 | err_str = "Invalid marker: {0!r}, parse error at {1!r}".format( | ||
| 279 | marker, marker[e.loc:e.loc + 8]) | ||
| 280 | raise InvalidMarker(err_str) | ||
| 281 | |||
| 282 | def __str__(self): | ||
| 283 | return _format_marker(self._markers) | ||
| 284 | |||
| 285 | def __repr__(self): | ||
| 286 | return "<Marker({0!r})>".format(str(self)) | ||
| 287 | |||
| 288 | def evaluate(self, environment=None): | ||
| 289 | """Evaluate a marker. | ||
| 290 | |||
| 291 | Return the boolean from evaluating the given marker against the | ||
| 292 | environment. environment is an optional argument to override all or | ||
| 293 | part of the determined environment. | ||
| 294 | |||
| 295 | The environment is determined from the current Python process. | ||
| 296 | """ | ||
| 297 | current_environment = default_environment() | ||
| 298 | if environment is not None: | ||
| 299 | current_environment.update(environment) | ||
| 300 | |||
| 301 | return _evaluate_markers(self._markers, current_environment) | ||
diff --git a/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/requirements.py b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/requirements.py new file mode 100644 index 0000000..98bc507 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/requirements.py | |||
| @@ -0,0 +1,130 @@ | |||
| 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 string | ||
| 7 | import re | ||
| 8 | |||
| 9 | from pip._vendor.pyparsing import stringStart, stringEnd, originalTextFor, ParseException | ||
| 10 | from pip._vendor.pyparsing import ZeroOrMore, Word, Optional, Regex, Combine | ||
| 11 | from pip._vendor.pyparsing import Literal as L # noqa | ||
| 12 | from pip._vendor.six.moves.urllib import parse as urlparse | ||
| 13 | |||
| 14 | from .markers import MARKER_EXPR, Marker | ||
| 15 | from .specifiers import LegacySpecifier, Specifier, SpecifierSet | ||
| 16 | |||
| 17 | |||
| 18 | class InvalidRequirement(ValueError): | ||
| 19 | """ | ||
| 20 | An invalid requirement was found, users should refer to PEP 508. | ||
| 21 | """ | ||
| 22 | |||
| 23 | |||
| 24 | ALPHANUM = Word(string.ascii_letters + string.digits) | ||
| 25 | |||
| 26 | LBRACKET = L("[").suppress() | ||
| 27 | RBRACKET = L("]").suppress() | ||
| 28 | LPAREN = L("(").suppress() | ||
| 29 | RPAREN = L(")").suppress() | ||
| 30 | COMMA = L(",").suppress() | ||
| 31 | SEMICOLON = L(";").suppress() | ||
| 32 | AT = L("@").suppress() | ||
| 33 | |||
| 34 | PUNCTUATION = Word("-_.") | ||
| 35 | IDENTIFIER_END = ALPHANUM | (ZeroOrMore(PUNCTUATION) + ALPHANUM) | ||
| 36 | IDENTIFIER = Combine(ALPHANUM + ZeroOrMore(IDENTIFIER_END)) | ||
| 37 | |||
| 38 | NAME = IDENTIFIER("name") | ||
| 39 | EXTRA = IDENTIFIER | ||
| 40 | |||
| 41 | URI = Regex(r'[^ ]+')("url") | ||
| 42 | URL = (AT + URI) | ||
| 43 | |||
| 44 | EXTRAS_LIST = EXTRA + ZeroOrMore(COMMA + EXTRA) | ||
| 45 | EXTRAS = (LBRACKET + Optional(EXTRAS_LIST) + RBRACKET)("extras") | ||
| 46 | |||
| 47 | VERSION_PEP440 = Regex(Specifier._regex_str, re.VERBOSE | re.IGNORECASE) | ||
| 48 | VERSION_LEGACY = Regex(LegacySpecifier._regex_str, re.VERBOSE | re.IGNORECASE) | ||
| 49 | |||
| 50 | VERSION_ONE = VERSION_PEP440 ^ VERSION_LEGACY | ||
| 51 | VERSION_MANY = Combine(VERSION_ONE + ZeroOrMore(COMMA + VERSION_ONE), | ||
| 52 | joinString=",", adjacent=False)("_raw_spec") | ||
| 53 | _VERSION_SPEC = Optional(((LPAREN + VERSION_MANY + RPAREN) | VERSION_MANY)) | ||
| 54 | _VERSION_SPEC.setParseAction(lambda s, l, t: t._raw_spec or '') | ||
| 55 | |||
| 56 | VERSION_SPEC = originalTextFor(_VERSION_SPEC)("specifier") | ||
| 57 | VERSION_SPEC.setParseAction(lambda s, l, t: t[1]) | ||
| 58 | |||
| 59 | MARKER_EXPR = originalTextFor(MARKER_EXPR())("marker") | ||
| 60 | MARKER_EXPR.setParseAction( | ||
| 61 | lambda s, l, t: Marker(s[t._original_start:t._original_end]) | ||
| 62 | ) | ||
| 63 | MARKER_SEPARATOR = SEMICOLON | ||
| 64 | MARKER = MARKER_SEPARATOR + MARKER_EXPR | ||
| 65 | |||
| 66 | VERSION_AND_MARKER = VERSION_SPEC + Optional(MARKER) | ||
| 67 | URL_AND_MARKER = URL + Optional(MARKER) | ||
| 68 | |||
| 69 | NAMED_REQUIREMENT = \ | ||
| 70 | NAME + Optional(EXTRAS) + (URL_AND_MARKER | VERSION_AND_MARKER) | ||
| 71 | |||
| 72 | REQUIREMENT = stringStart + NAMED_REQUIREMENT + stringEnd | ||
| 73 | # pyparsing isn't thread safe during initialization, so we do it eagerly, see | ||
| 74 | # issue #104 | ||
| 75 | REQUIREMENT.parseString("x[]") | ||
| 76 | |||
| 77 | |||
| 78 | class Requirement(object): | ||
| 79 | """Parse a requirement. | ||
| 80 | |||
| 81 | Parse a given requirement string into its parts, such as name, specifier, | ||
| 82 | URL, and extras. Raises InvalidRequirement on a badly-formed requirement | ||
| 83 | string. | ||
| 84 | """ | ||
| 85 | |||
| 86 | # TODO: Can we test whether something is contained within a requirement? | ||
| 87 | # If so how do we do that? Do we need to test against the _name_ of | ||
| 88 | # the thing as well as the version? What about the markers? | ||
| 89 | # TODO: Can we normalize the name and extra name? | ||
| 90 | |||
| 91 | def __init__(self, requirement_string): | ||
| 92 | try: | ||
| 93 | req = REQUIREMENT.parseString(requirement_string) | ||
| 94 | except ParseException as e: | ||
| 95 | raise InvalidRequirement( | ||
| 96 | "Invalid requirement, parse error at \"{0!r}\"".format( | ||
| 97 | requirement_string[e.loc:e.loc + 8])) | ||
| 98 | |||
| 99 | self.name = req.name | ||
| 100 | if req.url: | ||
| 101 | parsed_url = urlparse.urlparse(req.url) | ||
| 102 | if not (parsed_url.scheme and parsed_url.netloc) or ( | ||
| 103 | not parsed_url.scheme and not parsed_url.netloc): | ||
| 104 | raise InvalidRequirement("Invalid URL given") | ||
| 105 | self.url = req.url | ||
| 106 | else: | ||
| 107 | self.url = None | ||
| 108 | self.extras = set(req.extras.asList() if req.extras else []) | ||
| 109 | self.specifier = SpecifierSet(req.specifier) | ||
| 110 | self.marker = req.marker if req.marker else None | ||
| 111 | |||
| 112 | def __str__(self): | ||
| 113 | parts = [self.name] | ||
| 114 | |||
| 115 | if self.extras: | ||
| 116 | parts.append("[{0}]".format(",".join(sorted(self.extras)))) | ||
| 117 | |||
| 118 | if self.specifier: | ||
| 119 | parts.append(str(self.specifier)) | ||
| 120 | |||
| 121 | if self.url: | ||
| 122 | parts.append("@ {0}".format(self.url)) | ||
| 123 | |||
| 124 | if self.marker: | ||
| 125 | parts.append("; {0}".format(self.marker)) | ||
| 126 | |||
| 127 | return "".join(parts) | ||
| 128 | |||
| 129 | def __repr__(self): | ||
| 130 | return "<Requirement({0!r})>".format(str(self)) | ||
diff --git a/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/specifiers.py b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/specifiers.py new file mode 100644 index 0000000..7d2fe4c --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/specifiers.py | |||
| @@ -0,0 +1,774 @@ | |||
| 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 abc | ||
| 7 | import functools | ||
| 8 | import itertools | ||
| 9 | import re | ||
| 10 | |||
| 11 | from ._compat import string_types, with_metaclass | ||
| 12 | from .version import Version, LegacyVersion, parse | ||
| 13 | |||
| 14 | |||
| 15 | class InvalidSpecifier(ValueError): | ||
| 16 | """ | ||
| 17 | An invalid specifier was found, users should refer to PEP 440. | ||
| 18 | """ | ||
| 19 | |||
| 20 | |||
| 21 | class BaseSpecifier(with_metaclass(abc.ABCMeta, object)): | ||
| 22 | |||
| 23 | @abc.abstractmethod | ||
| 24 | def __str__(self): | ||
| 25 | """ | ||
| 26 | Returns the str representation of this Specifier like object. This | ||
| 27 | should be representative of the Specifier itself. | ||
| 28 | """ | ||
| 29 | |||
| 30 | @abc.abstractmethod | ||
| 31 | def __hash__(self): | ||
| 32 | """ | ||
| 33 | Returns a hash value for this Specifier like object. | ||
| 34 | """ | ||
| 35 | |||
| 36 | @abc.abstractmethod | ||
| 37 | def __eq__(self, other): | ||
| 38 | """ | ||
| 39 | Returns a boolean representing whether or not the two Specifier like | ||
| 40 | objects are equal. | ||
| 41 | """ | ||
| 42 | |||
| 43 | @abc.abstractmethod | ||
| 44 | def __ne__(self, other): | ||
| 45 | """ | ||
| 46 | Returns a boolean representing whether or not the two Specifier like | ||
| 47 | objects are not equal. | ||
| 48 | """ | ||
| 49 | |||
| 50 | @abc.abstractproperty | ||
| 51 | def prereleases(self): | ||
| 52 | """ | ||
| 53 | Returns whether or not pre-releases as a whole are allowed by this | ||
| 54 | specifier. | ||
| 55 | """ | ||
| 56 | |||
| 57 | @prereleases.setter | ||
| 58 | def prereleases(self, value): | ||
| 59 | """ | ||
| 60 | Sets whether or not pre-releases as a whole are allowed by this | ||
| 61 | specifier. | ||
| 62 | """ | ||
| 63 | |||
| 64 | @abc.abstractmethod | ||
| 65 | def contains(self, item, prereleases=None): | ||
| 66 | """ | ||
| 67 | Determines if the given item is contained within this specifier. | ||
| 68 | """ | ||
| 69 | |||
| 70 | @abc.abstractmethod | ||
| 71 | def filter(self, iterable, prereleases=None): | ||
| 72 | """ | ||
| 73 | Takes an iterable of items and filters them so that only items which | ||
| 74 | are contained within this specifier are allowed in it. | ||
| 75 | """ | ||
| 76 | |||
| 77 | |||
| 78 | class _IndividualSpecifier(BaseSpecifier): | ||
| 79 | |||
| 80 | _operators = {} | ||
| 81 | |||
| 82 | def __init__(self, spec="", prereleases=None): | ||
| 83 | match = self._regex.search(spec) | ||
| 84 | if not match: | ||
| 85 | raise InvalidSpecifier("Invalid specifier: '{0}'".format(spec)) | ||
| 86 | |||
| 87 | self._spec = ( | ||
| 88 | match.group("operator").strip(), | ||
| 89 | match.group("version").strip(), | ||
| 90 | ) | ||
| 91 | |||
| 92 | # Store whether or not this Specifier should accept prereleases | ||
| 93 | self._prereleases = prereleases | ||
| 94 | |||
| 95 | def __repr__(self): | ||
| 96 | pre = ( | ||
| 97 | ", prereleases={0!r}".format(self.prereleases) | ||
| 98 | if self._prereleases is not None | ||
| 99 | else "" | ||
| 100 | ) | ||
| 101 | |||
| 102 | return "<{0}({1!r}{2})>".format( | ||
| 103 | self.__class__.__name__, | ||
| 104 | str(self), | ||
| 105 | pre, | ||
| 106 | ) | ||
| 107 | |||
| 108 | def __str__(self): | ||
| 109 | return "{0}{1}".format(*self._spec) | ||
| 110 | |||
| 111 | def __hash__(self): | ||
| 112 | return hash(self._spec) | ||
| 113 | |||
| 114 | def __eq__(self, other): | ||
| 115 | if isinstance(other, string_types): | ||
| 116 | try: | ||
| 117 | other = self.__class__(other) | ||
| 118 | except InvalidSpecifier: | ||
| 119 | return NotImplemented | ||
| 120 | elif not isinstance(other, self.__class__): | ||
| 121 | return NotImplemented | ||
| 122 | |||
| 123 | return self._spec == other._spec | ||
| 124 | |||
| 125 | def __ne__(self, other): | ||
| 126 | if isinstance(other, string_types): | ||
| 127 | try: | ||
| 128 | other = self.__class__(other) | ||
| 129 | except InvalidSpecifier: | ||
| 130 | return NotImplemented | ||
| 131 | elif not isinstance(other, self.__class__): | ||
| 132 | return NotImplemented | ||
| 133 | |||
| 134 | return self._spec != other._spec | ||
| 135 | |||
| 136 | def _get_operator(self, op): | ||
| 137 | return getattr(self, "_compare_{0}".format(self._operators[op])) | ||
| 138 | |||
| 139 | def _coerce_version(self, version): | ||
| 140 | if not isinstance(version, (LegacyVersion, Version)): | ||
| 141 | version = parse(version) | ||
| 142 | return version | ||
| 143 | |||
| 144 | @property | ||
| 145 | def operator(self): | ||
| 146 | return self._spec[0] | ||
| 147 | |||
| 148 | @property | ||
| 149 | def version(self): | ||
| 150 | return self._spec[1] | ||
| 151 | |||
| 152 | @property | ||
| 153 | def prereleases(self): | ||
| 154 | return self._prereleases | ||
| 155 | |||
| 156 | @prereleases.setter | ||
| 157 | def prereleases(self, value): | ||
| 158 | self._prereleases = value | ||
| 159 | |||
| 160 | def __contains__(self, item): | ||
| 161 | return self.contains(item) | ||
| 162 | |||
| 163 | def contains(self, item, prereleases=None): | ||
| 164 | # Determine if prereleases are to be allowed or not. | ||
| 165 | if prereleases is None: | ||
| 166 | prereleases = self.prereleases | ||
| 167 | |||
| 168 | # Normalize item to a Version or LegacyVersion, this allows us to have | ||
| 169 | # a shortcut for ``"2.0" in Specifier(">=2") | ||
| 170 | item = self._coerce_version(item) | ||
| 171 | |||
| 172 | # Determine if we should be supporting prereleases in this specifier | ||
| 173 | # or not, if we do not support prereleases than we can short circuit | ||
| 174 | # logic if this version is a prereleases. | ||
| 175 | if item.is_prerelease and not prereleases: | ||
| 176 | return False | ||
| 177 | |||
| 178 | # Actually do the comparison to determine if this item is contained | ||
| 179 | # within this Specifier or not. | ||
| 180 | return self._get_operator(self.operator)(item, self.version) | ||
| 181 | |||
| 182 | def filter(self, iterable, prereleases=None): | ||
| 183 | yielded = False | ||
| 184 | found_prereleases = [] | ||
| 185 | |||
| 186 | kw = {"prereleases": prereleases if prereleases is not None else True} | ||
| 187 | |||
| 188 | # Attempt to iterate over all the values in the iterable and if any of | ||
| 189 | # them match, yield them. | ||
| 190 | for version in iterable: | ||
| 191 | parsed_version = self._coerce_version(version) | ||
| 192 | |||
| 193 | if self.contains(parsed_version, **kw): | ||
| 194 | # If our version is a prerelease, and we were not set to allow | ||
| 195 | # prereleases, then we'll store it for later incase nothing | ||
| 196 | # else matches this specifier. | ||
| 197 | if (parsed_version.is_prerelease and not | ||
| 198 | (prereleases or self.prereleases)): | ||
| 199 | found_prereleases.append(version) | ||
| 200 | # Either this is not a prerelease, or we should have been | ||
| 201 | # accepting prereleases from the beginning. | ||
| 202 | else: | ||
| 203 | yielded = True | ||
| 204 | yield version | ||
| 205 | |||
| 206 | # Now that we've iterated over everything, determine if we've yielded | ||
| 207 | # any values, and if we have not and we have any prereleases stored up | ||
| 208 | # then we will go ahead and yield the prereleases. | ||
| 209 | if not yielded and found_prereleases: | ||
| 210 | for version in found_prereleases: | ||
| 211 | yield version | ||
| 212 | |||
| 213 | |||
| 214 | class LegacySpecifier(_IndividualSpecifier): | ||
| 215 | |||
| 216 | _regex_str = ( | ||
| 217 | r""" | ||
| 218 | (?P<operator>(==|!=|<=|>=|<|>)) | ||
| 219 | \s* | ||
| 220 | (?P<version> | ||
| 221 | [^,;\s)]* # Since this is a "legacy" specifier, and the version | ||
| 222 | # string can be just about anything, we match everything | ||
| 223 | # except for whitespace, a semi-colon for marker support, | ||
| 224 | # a closing paren since versions can be enclosed in | ||
| 225 | # them, and a comma since it's a version separator. | ||
| 226 | ) | ||
| 227 | """ | ||
| 228 | ) | ||
| 229 | |||
| 230 | _regex = re.compile( | ||
| 231 | r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE) | ||
| 232 | |||
| 233 | _operators = { | ||
| 234 | "==": "equal", | ||
| 235 | "!=": "not_equal", | ||
| 236 | "<=": "less_than_equal", | ||
| 237 | ">=": "greater_than_equal", | ||
| 238 | "<": "less_than", | ||
| 239 | ">": "greater_than", | ||
| 240 | } | ||
| 241 | |||
| 242 | def _coerce_version(self, version): | ||
| 243 | if not isinstance(version, LegacyVersion): | ||
| 244 | version = LegacyVersion(str(version)) | ||
| 245 | return version | ||
| 246 | |||
| 247 | def _compare_equal(self, prospective, spec): | ||
| 248 | return prospective == self._coerce_version(spec) | ||
| 249 | |||
| 250 | def _compare_not_equal(self, prospective, spec): | ||
| 251 | return prospective != self._coerce_version(spec) | ||
| 252 | |||
| 253 | def _compare_less_than_equal(self, prospective, spec): | ||
| 254 | return prospective <= self._coerce_version(spec) | ||
| 255 | |||
| 256 | def _compare_greater_than_equal(self, prospective, spec): | ||
| 257 | return prospective >= self._coerce_version(spec) | ||
| 258 | |||
| 259 | def _compare_less_than(self, prospective, spec): | ||
| 260 | return prospective < self._coerce_version(spec) | ||
| 261 | |||
| 262 | def _compare_greater_than(self, prospective, spec): | ||
| 263 | return prospective > self._coerce_version(spec) | ||
| 264 | |||
| 265 | |||
| 266 | def _require_version_compare(fn): | ||
| 267 | @functools.wraps(fn) | ||
| 268 | def wrapped(self, prospective, spec): | ||
| 269 | if not isinstance(prospective, Version): | ||
| 270 | return False | ||
| 271 | return fn(self, prospective, spec) | ||
| 272 | return wrapped | ||
| 273 | |||
| 274 | |||
| 275 | class Specifier(_IndividualSpecifier): | ||
| 276 | |||
| 277 | _regex_str = ( | ||
| 278 | r""" | ||
| 279 | (?P<operator>(~=|==|!=|<=|>=|<|>|===)) | ||
| 280 | (?P<version> | ||
| 281 | (?: | ||
| 282 | # The identity operators allow for an escape hatch that will | ||
| 283 | # do an exact string match of the version you wish to install. | ||
| 284 | # This will not be parsed by PEP 440 and we cannot determine | ||
| 285 | # any semantic meaning from it. This operator is discouraged | ||
| 286 | # but included entirely as an escape hatch. | ||
| 287 | (?<====) # Only match for the identity operator | ||
| 288 | \s* | ||
| 289 | [^\s]* # We just match everything, except for whitespace | ||
| 290 | # since we are only testing for strict identity. | ||
| 291 | ) | ||
| 292 | | | ||
| 293 | (?: | ||
| 294 | # The (non)equality operators allow for wild card and local | ||
| 295 | # versions to be specified so we have to define these two | ||
| 296 | # operators separately to enable that. | ||
| 297 | (?<===|!=) # Only match for equals and not equals | ||
| 298 | |||
| 299 | \s* | ||
| 300 | v? | ||
| 301 | (?:[0-9]+!)? # epoch | ||
| 302 | [0-9]+(?:\.[0-9]+)* # release | ||
| 303 | (?: # pre release | ||
| 304 | [-_\.]? | ||
| 305 | (a|b|c|rc|alpha|beta|pre|preview) | ||
| 306 | [-_\.]? | ||
| 307 | [0-9]* | ||
| 308 | )? | ||
| 309 | (?: # post release | ||
| 310 | (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) | ||
| 311 | )? | ||
| 312 | |||
| 313 | # You cannot use a wild card and a dev or local version | ||
| 314 | # together so group them with a | and make them optional. | ||
| 315 | (?: | ||
| 316 | (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release | ||
| 317 | (?:\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*)? # local | ||
| 318 | | | ||
| 319 | \.\* # Wild card syntax of .* | ||
| 320 | )? | ||
| 321 | ) | ||
| 322 | | | ||
| 323 | (?: | ||
| 324 | # The compatible operator requires at least two digits in the | ||
| 325 | # release segment. | ||
| 326 | (?<=~=) # Only match for the compatible operator | ||
| 327 | |||
| 328 | \s* | ||
| 329 | v? | ||
| 330 | (?:[0-9]+!)? # epoch | ||
| 331 | [0-9]+(?:\.[0-9]+)+ # release (We have a + instead of a *) | ||
| 332 | (?: # pre release | ||
| 333 | [-_\.]? | ||
| 334 | (a|b|c|rc|alpha|beta|pre|preview) | ||
| 335 | [-_\.]? | ||
| 336 | [0-9]* | ||
| 337 | )? | ||
| 338 | (?: # post release | ||
| 339 | (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) | ||
| 340 | )? | ||
| 341 | (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release | ||
| 342 | ) | ||
| 343 | | | ||
| 344 | (?: | ||
| 345 | # All other operators only allow a sub set of what the | ||
| 346 | # (non)equality operators do. Specifically they do not allow | ||
| 347 | # local versions to be specified nor do they allow the prefix | ||
| 348 | # matching wild cards. | ||
| 349 | (?<!==|!=|~=) # We have special cases for these | ||
| 350 | # operators so we want to make sure they | ||
| 351 | # don't match here. | ||
| 352 | |||
| 353 | \s* | ||
| 354 | v? | ||
| 355 | (?:[0-9]+!)? # epoch | ||
| 356 | [0-9]+(?:\.[0-9]+)* # release | ||
| 357 | (?: # pre release | ||
| 358 | [-_\.]? | ||
| 359 | (a|b|c|rc|alpha|beta|pre|preview) | ||
| 360 | [-_\.]? | ||
| 361 | [0-9]* | ||
| 362 | )? | ||
| 363 | (?: # post release | ||
| 364 | (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) | ||
| 365 | )? | ||
| 366 | (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release | ||
| 367 | ) | ||
| 368 | ) | ||
| 369 | """ | ||
| 370 | ) | ||
| 371 | |||
| 372 | _regex = re.compile( | ||
| 373 | r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE) | ||
| 374 | |||
| 375 | _operators = { | ||
| 376 | "~=": "compatible", | ||
| 377 | "==": "equal", | ||
| 378 | "!=": "not_equal", | ||
| 379 | "<=": "less_than_equal", | ||
| 380 | ">=": "greater_than_equal", | ||
| 381 | "<": "less_than", | ||
| 382 | ">": "greater_than", | ||
| 383 | "===": "arbitrary", | ||
| 384 | } | ||
| 385 | |||
| 386 | @_require_version_compare | ||
| 387 | def _compare_compatible(self, prospective, spec): | ||
| 388 | # Compatible releases have an equivalent combination of >= and ==. That | ||
| 389 | # is that ~=2.2 is equivalent to >=2.2,==2.*. This allows us to | ||
| 390 | # implement this in terms of the other specifiers instead of | ||
| 391 | # implementing it ourselves. The only thing we need to do is construct | ||
| 392 | # the other specifiers. | ||
| 393 | |||
| 394 | # We want everything but the last item in the version, but we want to | ||
| 395 | # ignore post and dev releases and we want to treat the pre-release as | ||
| 396 | # it's own separate segment. | ||
| 397 | prefix = ".".join( | ||
| 398 | list( | ||
| 399 | itertools.takewhile( | ||
| 400 | lambda x: (not x.startswith("post") and not | ||
| 401 | x.startswith("dev")), | ||
| 402 | _version_split(spec), | ||
| 403 | ) | ||
| 404 | )[:-1] | ||
| 405 | ) | ||
| 406 | |||
| 407 | # Add the prefix notation to the end of our string | ||
| 408 | prefix += ".*" | ||
| 409 | |||
| 410 | return (self._get_operator(">=")(prospective, spec) and | ||
| 411 | self._get_operator("==")(prospective, prefix)) | ||
| 412 | |||
| 413 | @_require_version_compare | ||
| 414 | def _compare_equal(self, prospective, spec): | ||
| 415 | # We need special logic to handle prefix matching | ||
| 416 | if spec.endswith(".*"): | ||
| 417 | # In the case of prefix matching we want to ignore local segment. | ||
| 418 | prospective = Version(prospective.public) | ||
| 419 | # Split the spec out by dots, and pretend that there is an implicit | ||
| 420 | # dot in between a release segment and a pre-release segment. | ||
| 421 | spec = _version_split(spec[:-2]) # Remove the trailing .* | ||
| 422 | |||
| 423 | # Split the prospective version out by dots, and pretend that there | ||
| 424 | # is an implicit dot in between a release segment and a pre-release | ||
| 425 | # segment. | ||
| 426 | prospective = _version_split(str(prospective)) | ||
| 427 | |||
| 428 | # Shorten the prospective version to be the same length as the spec | ||
| 429 | # so that we can determine if the specifier is a prefix of the | ||
| 430 | # prospective version or not. | ||
| 431 | prospective = prospective[:len(spec)] | ||
| 432 | |||
| 433 | # Pad out our two sides with zeros so that they both equal the same | ||
| 434 | # length. | ||
| 435 | spec, prospective = _pad_version(spec, prospective) | ||
| 436 | else: | ||
| 437 | # Convert our spec string into a Version | ||
| 438 | spec = Version(spec) | ||
| 439 | |||
| 440 | # If the specifier does not have a local segment, then we want to | ||
| 441 | # act as if the prospective version also does not have a local | ||
| 442 | # segment. | ||
| 443 | if not spec.local: | ||
| 444 | prospective = Version(prospective.public) | ||
| 445 | |||
| 446 | return prospective == spec | ||
| 447 | |||
| 448 | @_require_version_compare | ||
| 449 | def _compare_not_equal(self, prospective, spec): | ||
| 450 | return not self._compare_equal(prospective, spec) | ||
| 451 | |||
| 452 | @_require_version_compare | ||
| 453 | def _compare_less_than_equal(self, prospective, spec): | ||
| 454 | return prospective <= Version(spec) | ||
| 455 | |||
| 456 | @_require_version_compare | ||
| 457 | def _compare_greater_than_equal(self, prospective, spec): | ||
| 458 | return prospective >= Version(spec) | ||
| 459 | |||
| 460 | @_require_version_compare | ||
| 461 | def _compare_less_than(self, prospective, spec): | ||
| 462 | # Convert our spec to a Version instance, since we'll want to work with | ||
| 463 | # it as a version. | ||
| 464 | spec = Version(spec) | ||
| 465 | |||
| 466 | # Check to see if the prospective version is less than the spec | ||
| 467 | # version. If it's not we can short circuit and just return False now | ||
| 468 | # instead of doing extra unneeded work. | ||
| 469 | if not prospective < spec: | ||
| 470 | return False | ||
| 471 | |||
| 472 | # This special case is here so that, unless the specifier itself | ||
| 473 | # includes is a pre-release version, that we do not accept pre-release | ||
| 474 | # versions for the version mentioned in the specifier (e.g. <3.1 should | ||
| 475 | # not match 3.1.dev0, but should match 3.0.dev0). | ||
| 476 | if not spec.is_prerelease and prospective.is_prerelease: | ||
| 477 | if Version(prospective.base_version) == Version(spec.base_version): | ||
| 478 | return False | ||
| 479 | |||
| 480 | # If we've gotten to here, it means that prospective version is both | ||
| 481 | # less than the spec version *and* it's not a pre-release of the same | ||
| 482 | # version in the spec. | ||
| 483 | return True | ||
| 484 | |||
| 485 | @_require_version_compare | ||
| 486 | def _compare_greater_than(self, prospective, spec): | ||
| 487 | # Convert our spec to a Version instance, since we'll want to work with | ||
| 488 | # it as a version. | ||
| 489 | spec = Version(spec) | ||
| 490 | |||
| 491 | # Check to see if the prospective version is greater than the spec | ||
| 492 | # version. If it's not we can short circuit and just return False now | ||
| 493 | # instead of doing extra unneeded work. | ||
| 494 | if not prospective > spec: | ||
| 495 | return False | ||
| 496 | |||
| 497 | # This special case is here so that, unless the specifier itself | ||
| 498 | # includes is a post-release version, that we do not accept | ||
| 499 | # post-release versions for the version mentioned in the specifier | ||
| 500 | # (e.g. >3.1 should not match 3.0.post0, but should match 3.2.post0). | ||
| 501 | if not spec.is_postrelease and prospective.is_postrelease: | ||
| 502 | if Version(prospective.base_version) == Version(spec.base_version): | ||
| 503 | return False | ||
| 504 | |||
| 505 | # Ensure that we do not allow a local version of the version mentioned | ||
| 506 | # in the specifier, which is techincally greater than, to match. | ||
| 507 | if prospective.local is not None: | ||
| 508 | if Version(prospective.base_version) == Version(spec.base_version): | ||
| 509 | return False | ||
| 510 | |||
| 511 | # If we've gotten to here, it means that prospective version is both | ||
| 512 | # greater than the spec version *and* it's not a pre-release of the | ||
| 513 | # same version in the spec. | ||
| 514 | return True | ||
| 515 | |||
| 516 | def _compare_arbitrary(self, prospective, spec): | ||
| 517 | return str(prospective).lower() == str(spec).lower() | ||
| 518 | |||
| 519 | @property | ||
| 520 | def prereleases(self): | ||
| 521 | # If there is an explicit prereleases set for this, then we'll just | ||
| 522 | # blindly use that. | ||
| 523 | if self._prereleases is not None: | ||
| 524 | return self._prereleases | ||
| 525 | |||
| 526 | # Look at all of our specifiers and determine if they are inclusive | ||
| 527 | # operators, and if they are if they are including an explicit | ||
| 528 | # prerelease. | ||
| 529 | operator, version = self._spec | ||
| 530 | if operator in ["==", ">=", "<=", "~=", "==="]: | ||
| 531 | # The == specifier can include a trailing .*, if it does we | ||
| 532 | # want to remove before parsing. | ||
| 533 | if operator == "==" and version.endswith(".*"): | ||
| 534 | version = version[:-2] | ||
| 535 | |||
| 536 | # Parse the version, and if it is a pre-release than this | ||
| 537 | # specifier allows pre-releases. | ||
| 538 | if parse(version).is_prerelease: | ||
| 539 | return True | ||
| 540 | |||
| 541 | return False | ||
| 542 | |||
| 543 | @prereleases.setter | ||
| 544 | def prereleases(self, value): | ||
| 545 | self._prereleases = value | ||
| 546 | |||
| 547 | |||
| 548 | _prefix_regex = re.compile(r"^([0-9]+)((?:a|b|c|rc)[0-9]+)$") | ||
| 549 | |||
| 550 | |||
| 551 | def _version_split(version): | ||
| 552 | result = [] | ||
| 553 | for item in version.split("."): | ||
| 554 | match = _prefix_regex.search(item) | ||
| 555 | if match: | ||
| 556 | result.extend(match.groups()) | ||
| 557 | else: | ||
| 558 | result.append(item) | ||
| 559 | return result | ||
| 560 | |||
| 561 | |||
| 562 | def _pad_version(left, right): | ||
| 563 | left_split, right_split = [], [] | ||
| 564 | |||
| 565 | # Get the release segment of our versions | ||
| 566 | left_split.append(list(itertools.takewhile(lambda x: x.isdigit(), left))) | ||
| 567 | right_split.append(list(itertools.takewhile(lambda x: x.isdigit(), right))) | ||
| 568 | |||
| 569 | # Get the rest of our versions | ||
| 570 | left_split.append(left[len(left_split[0]):]) | ||
| 571 | right_split.append(right[len(right_split[0]):]) | ||
| 572 | |||
| 573 | # Insert our padding | ||
| 574 | left_split.insert( | ||
| 575 | 1, | ||
| 576 | ["0"] * max(0, len(right_split[0]) - len(left_split[0])), | ||
| 577 | ) | ||
| 578 | right_split.insert( | ||
| 579 | 1, | ||
| 580 | ["0"] * max(0, len(left_split[0]) - len(right_split[0])), | ||
| 581 | ) | ||
| 582 | |||
| 583 | return ( | ||
| 584 | list(itertools.chain(*left_split)), | ||
| 585 | list(itertools.chain(*right_split)), | ||
| 586 | ) | ||
| 587 | |||
| 588 | |||
| 589 | class SpecifierSet(BaseSpecifier): | ||
| 590 | |||
| 591 | def __init__(self, specifiers="", prereleases=None): | ||
| 592 | # Split on , to break each indidivual specifier into it's own item, and | ||
| 593 | # strip each item to remove leading/trailing whitespace. | ||
| 594 | specifiers = [s.strip() for s in specifiers.split(",") if s.strip()] | ||
| 595 | |||
| 596 | # Parsed each individual specifier, attempting first to make it a | ||
| 597 | # Specifier and falling back to a LegacySpecifier. | ||
| 598 | parsed = set() | ||
| 599 | for specifier in specifiers: | ||
| 600 | try: | ||
| 601 | parsed.add(Specifier(specifier)) | ||
| 602 | except InvalidSpecifier: | ||
| 603 | parsed.add(LegacySpecifier(specifier)) | ||
| 604 | |||
| 605 | # Turn our parsed specifiers into a frozen set and save them for later. | ||
| 606 | self._specs = frozenset(parsed) | ||
| 607 | |||
| 608 | # Store our prereleases value so we can use it later to determine if | ||
| 609 | # we accept prereleases or not. | ||
| 610 | self._prereleases = prereleases | ||
| 611 | |||
| 612 | def __repr__(self): | ||
| 613 | pre = ( | ||
| 614 | ", prereleases={0!r}".format(self.prereleases) | ||
| 615 | if self._prereleases is not None | ||
| 616 | else "" | ||
| 617 | ) | ||
| 618 | |||
| 619 | return "<SpecifierSet({0!r}{1})>".format(str(self), pre) | ||
| 620 | |||
| 621 | def __str__(self): | ||
| 622 | return ",".join(sorted(str(s) for s in self._specs)) | ||
| 623 | |||
| 624 | def __hash__(self): | ||
| 625 | return hash(self._specs) | ||
| 626 | |||
| 627 | def __and__(self, other): | ||
| 628 | if isinstance(other, string_types): | ||
| 629 | other = SpecifierSet(other) | ||
| 630 | elif not isinstance(other, SpecifierSet): | ||
| 631 | return NotImplemented | ||
| 632 | |||
| 633 | specifier = SpecifierSet() | ||
| 634 | specifier._specs = frozenset(self._specs | other._specs) | ||
| 635 | |||
| 636 | if self._prereleases is None and other._prereleases is not None: | ||
| 637 | specifier._prereleases = other._prereleases | ||
| 638 | elif self._prereleases is not None and other._prereleases is None: | ||
| 639 | specifier._prereleases = self._prereleases | ||
| 640 | elif self._prereleases == other._prereleases: | ||
| 641 | specifier._prereleases = self._prereleases | ||
| 642 | else: | ||
| 643 | raise ValueError( | ||
| 644 | "Cannot combine SpecifierSets with True and False prerelease " | ||
| 645 | "overrides." | ||
| 646 | ) | ||
| 647 | |||
| 648 | return specifier | ||
| 649 | |||
| 650 | def __eq__(self, other): | ||
| 651 | if isinstance(other, string_types): | ||
| 652 | other = SpecifierSet(other) | ||
| 653 | elif isinstance(other, _IndividualSpecifier): | ||
| 654 | other = SpecifierSet(str(other)) | ||
| 655 | elif not isinstance(other, SpecifierSet): | ||
| 656 | return NotImplemented | ||
| 657 | |||
| 658 | return self._specs == other._specs | ||
| 659 | |||
| 660 | def __ne__(self, other): | ||
| 661 | if isinstance(other, string_types): | ||
| 662 | other = SpecifierSet(other) | ||
| 663 | elif isinstance(other, _IndividualSpecifier): | ||
| 664 | other = SpecifierSet(str(other)) | ||
| 665 | elif not isinstance(other, SpecifierSet): | ||
| 666 | return NotImplemented | ||
| 667 | |||
| 668 | return self._specs != other._specs | ||
| 669 | |||
| 670 | def __len__(self): | ||
| 671 | return len(self._specs) | ||
| 672 | |||
| 673 | def __iter__(self): | ||
| 674 | return iter(self._specs) | ||
| 675 | |||
| 676 | @property | ||
| 677 | def prereleases(self): | ||
| 678 | # If we have been given an explicit prerelease modifier, then we'll | ||
| 679 | # pass that through here. | ||
| 680 | if self._prereleases is not None: | ||
| 681 | return self._prereleases | ||
| 682 | |||
| 683 | # If we don't have any specifiers, and we don't have a forced value, | ||
| 684 | # then we'll just return None since we don't know if this should have | ||
| 685 | # pre-releases or not. | ||
| 686 | if not self._specs: | ||
| 687 | return None | ||
| 688 | |||
| 689 | # Otherwise we'll see if any of the given specifiers accept | ||
| 690 | # prereleases, if any of them do we'll return True, otherwise False. | ||
| 691 | return any(s.prereleases for s in self._specs) | ||
| 692 | |||
| 693 | @prereleases.setter | ||
| 694 | def prereleases(self, value): | ||
| 695 | self._prereleases = value | ||
| 696 | |||
| 697 | def __contains__(self, item): | ||
| 698 | return self.contains(item) | ||
| 699 | |||
| 700 | def contains(self, item, prereleases=None): | ||
| 701 | # Ensure that our item is a Version or LegacyVersion instance. | ||
| 702 | if not isinstance(item, (LegacyVersion, Version)): | ||
| 703 | item = parse(item) | ||
| 704 | |||
| 705 | # Determine if we're forcing a prerelease or not, if we're not forcing | ||
| 706 | # one for this particular filter call, then we'll use whatever the | ||
| 707 | # SpecifierSet thinks for whether or not we should support prereleases. | ||
| 708 | if prereleases is None: | ||
| 709 | prereleases = self.prereleases | ||
| 710 | |||
| 711 | # We can determine if we're going to allow pre-releases by looking to | ||
| 712 | # see if any of the underlying items supports them. If none of them do | ||
| 713 | # and this item is a pre-release then we do not allow it and we can | ||
| 714 | # short circuit that here. | ||
| 715 | # Note: This means that 1.0.dev1 would not be contained in something | ||
| 716 | # like >=1.0.devabc however it would be in >=1.0.debabc,>0.0.dev0 | ||
| 717 | if not prereleases and item.is_prerelease: | ||
| 718 | return False | ||
| 719 | |||
| 720 | # We simply dispatch to the underlying specs here to make sure that the | ||
| 721 | # given version is contained within all of them. | ||
| 722 | # Note: This use of all() here means that an empty set of specifiers | ||
| 723 | # will always return True, this is an explicit design decision. | ||
| 724 | return all( | ||
| 725 | s.contains(item, prereleases=prereleases) | ||
| 726 | for s in self._specs | ||
| 727 | ) | ||
| 728 | |||
| 729 | def filter(self, iterable, prereleases=None): | ||
| 730 | # Determine if we're forcing a prerelease or not, if we're not forcing | ||
| 731 | # one for this particular filter call, then we'll use whatever the | ||
| 732 | # SpecifierSet thinks for whether or not we should support prereleases. | ||
| 733 | if prereleases is None: | ||
| 734 | prereleases = self.prereleases | ||
| 735 | |||
| 736 | # If we have any specifiers, then we want to wrap our iterable in the | ||
| 737 | # filter method for each one, this will act as a logical AND amongst | ||
| 738 | # each specifier. | ||
| 739 | if self._specs: | ||
| 740 | for spec in self._specs: | ||
| 741 | iterable = spec.filter(iterable, prereleases=bool(prereleases)) | ||
| 742 | return iterable | ||
| 743 | # If we do not have any specifiers, then we need to have a rough filter | ||
| 744 | # which will filter out any pre-releases, unless there are no final | ||
| 745 | # releases, and which will filter out LegacyVersion in general. | ||
| 746 | else: | ||
| 747 | filtered = [] | ||
| 748 | found_prereleases = [] | ||
| 749 | |||
| 750 | for item in iterable: | ||
| 751 | # Ensure that we some kind of Version class for this item. | ||
| 752 | if not isinstance(item, (LegacyVersion, Version)): | ||
| 753 | parsed_version = parse(item) | ||
| 754 | else: | ||
| 755 | parsed_version = item | ||
| 756 | |||
| 757 | # Filter out any item which is parsed as a LegacyVersion | ||
| 758 | if isinstance(parsed_version, LegacyVersion): | ||
| 759 | continue | ||
| 760 | |||
| 761 | # Store any item which is a pre-release for later unless we've | ||
| 762 | # already found a final version or we are accepting prereleases | ||
| 763 | if parsed_version.is_prerelease and not prereleases: | ||
| 764 | if not filtered: | ||
| 765 | found_prereleases.append(item) | ||
| 766 | else: | ||
| 767 | filtered.append(item) | ||
| 768 | |||
| 769 | # If we've found no items except for pre-releases, then we'll go | ||
| 770 | # ahead and use the pre-releases | ||
| 771 | if not filtered and found_prereleases and prereleases is None: | ||
| 772 | return found_prereleases | ||
| 773 | |||
| 774 | return filtered | ||
diff --git a/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/utils.py b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/utils.py new file mode 100644 index 0000000..5151f9f --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/utils.py | |||
| @@ -0,0 +1,63 @@ | |||
| 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 re | ||
| 7 | |||
| 8 | from .version import InvalidVersion, Version | ||
| 9 | |||
| 10 | |||
| 11 | _canonicalize_regex = re.compile(r"[-_.]+") | ||
| 12 | |||
| 13 | |||
| 14 | def canonicalize_name(name): | ||
| 15 | # This is taken from PEP 503. | ||
| 16 | return _canonicalize_regex.sub("-", name).lower() | ||
| 17 | |||
| 18 | |||
| 19 | def canonicalize_version(version): | ||
| 20 | """ | ||
| 21 | This is very similar to Version.__str__, but has one subtle differences | ||
| 22 | with the way it handles the release segment. | ||
| 23 | """ | ||
| 24 | |||
| 25 | try: | ||
| 26 | version = Version(version) | ||
| 27 | except InvalidVersion: | ||
| 28 | # Legacy versions cannot be normalized | ||
| 29 | return version | ||
| 30 | |||
| 31 | parts = [] | ||
| 32 | |||
| 33 | # Epoch | ||
| 34 | if version.epoch != 0: | ||
| 35 | parts.append("{0}!".format(version.epoch)) | ||
| 36 | |||
| 37 | # Release segment | ||
| 38 | # NB: This strips trailing '.0's to normalize | ||
| 39 | parts.append( | ||
| 40 | re.sub( | ||
| 41 | r'(\.0)+$', | ||
| 42 | '', | ||
| 43 | ".".join(str(x) for x in version.release) | ||
| 44 | ) | ||
| 45 | ) | ||
| 46 | |||
| 47 | # Pre-release | ||
| 48 | if version.pre is not None: | ||
| 49 | parts.append("".join(str(x) for x in version.pre)) | ||
| 50 | |||
| 51 | # Post-release | ||
| 52 | if version.post is not None: | ||
| 53 | parts.append(".post{0}".format(version.post)) | ||
| 54 | |||
| 55 | # Development release | ||
| 56 | if version.dev is not None: | ||
| 57 | parts.append(".dev{0}".format(version.dev)) | ||
| 58 | |||
| 59 | # Local version segment | ||
| 60 | if version.local is not None: | ||
| 61 | parts.append("+{0}".format(version.local)) | ||
| 62 | |||
| 63 | return "".join(parts) | ||
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 new file mode 100644 index 0000000..a8affbd --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/version.py | |||
| @@ -0,0 +1,441 @@ | |||
| 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 | ||
