9from typing
import Callable, Iterator, List, Optional, SupportsInt, Tuple, Union
11from ._structures
import Infinity, InfinityType, NegativeInfinity, NegativeInfinityType
13__all__ = [
"parse",
"Version",
"LegacyVersion",
"InvalidVersion",
"VERSION_PATTERN"]
15InfiniteTypes = Union[InfinityType, NegativeInfinityType]
16PrePostDevType = Union[InfiniteTypes, Tuple[str, int]]
17SubLocalType = Union[InfiniteTypes, int, str]
23 Tuple[SubLocalType, str],
24 Tuple[NegativeInfinityType, SubLocalType],
30 int, Tuple[int, ...], PrePostDevType, PrePostDevType, PrePostDevType, LocalType
32LegacyCmpKey = Tuple[int, Tuple[str, ...]]
33VersionComparisonMethod = Callable[
34 [Union[CmpKey, LegacyCmpKey], Union[CmpKey, LegacyCmpKey]], bool
38 "_Version", [
"epoch",
"release",
"dev",
"pre",
"post",
"local"]
42def parse(version: str) -> Union[
"LegacyVersion",
"Version"]:
44 Parse the given version string and return either a :class:`Version` object
45 or a :class:`LegacyVersion` object depending on if the given version is
46 a valid PEP 440 version or a legacy version.
50 except InvalidVersion:
56 An invalid version was found, users should refer to PEP 440.
61 _key: Union[CmpKey, LegacyCmpKey]
69 def __lt__(self, other:
"_BaseVersion") -> bool:
75 def __le__(self, other:
"_BaseVersion") -> bool:
81 def __eq__(self, other: object) -> bool:
87 def __ge__(self, other:
"_BaseVersion") -> bool:
93 def __gt__(self, other:
"_BaseVersion") -> bool:
99 def __ne__(self, other: object) -> bool:
101 return NotImplemented
112 "Creating a LegacyVersion has been deprecated and will be "
113 "removed in the next major release",
121 return f
"<LegacyVersion('{self}')>"
144 def post(self) -> None:
170_legacy_version_replacement_map = {
183 if not part
or part ==
".":
186 if part[:1]
in "0123456789":
206 parts: List[str] = []
211 while parts
and parts[-1] ==
"*final-":
215 while parts
and parts[-1] ==
"00000000":
220 return epoch, tuple(parts)
225VERSION_PATTERN =
r"""
228 (?:(?P<epoch>[0-9]+)!)? # epoch
229 (?P<release>[0-9]+(?:\.[0-9]+)*) # release segment
230 (?P<pre> # pre-release
232 (?P<pre_l>(a|b|c|rc|alpha|beta|pre|preview))
236 (?P<post> # post release
237 (?:-(?P<post_n1>[0-9]+))
241 (?P<post_l>post|rev|r)
246 (?P<dev> # dev release
253 (?:\+(?P<local>[a-z0-9]+(?:[-_\.][a-z0-9]+)*))? # local version
264 match = self.
_regex.search(version)
271 release=tuple(int(i)
for i
in match.group(
"release").split(
".")),
291 return f
"<Version('{self}')>"
304 if self.
prepre is not None:
308 if self.
post is not None:
312 if self.
dev is not None:
316 if self.
local is not None:
319 return "".join(parts)
328 _release: Tuple[int, ...] = self.
_version.release
332 def pre(self) -> Optional[Tuple[str, int]]:
333 _pre: Optional[Tuple[str, int]] = self.
_version.pre
337 def post(self) -> Optional[int]:
341 def dev(self) -> Optional[int]:
347 return ".".join(str(x)
for x
in self.
_version.local)
353 return str(self).split(
"+", 1)[0]
366 return "".join(parts)
370 return self.
dev is not None or self.
prepre is not None
374 return self.
post is not None
378 return self.
dev is not None
394 letter: str, number: Union[str, bytes, SupportsInt]
395) -> Optional[Tuple[str, int]]:
409 if letter ==
"alpha":
411 elif letter ==
"beta":
413 elif letter
in [
"c",
"pre",
"preview"]:
415 elif letter
in [
"rev",
"r"]:
418 return letter, int(number)
419 if not letter
and number:
424 return letter, int(number)
434 Takes a string like abc.1.twelve and turns it into ("abc", 1, "twelve").
436 if local
is not None:
446 release: Tuple[int, ...],
447 pre: Optional[Tuple[str, int]],
448 post: Optional[Tuple[str, int]],
449 dev: Optional[Tuple[str, int]],
450 local: Optional[Tuple[SubLocalType]],
466 if pre
is None and post
is None and dev
is not None:
467 _pre: PrePostDevType = NegativeInfinity
477 _post: PrePostDevType = NegativeInfinity
484 _dev: PrePostDevType = Infinity
491 _local: LocalType = NegativeInfinity
501 (i,
"")
if isinstance(i, int)
else (NegativeInfinity, i)
for i
in local
504 return epoch, _release, _pre, _post, _dev, _local
bool is_postrelease(self)
None __init__(self, str version)
Optional[str] local(self)
bool is_postrelease(self)
Tuple[int,...] release(self)
None __init__(self, str version)
Optional[Tuple[str, int]] pre(self)
bool __lt__(self, "_BaseVersion" other)
bool __eq__(self, object other)
bool __le__(self, "_BaseVersion" other)
bool __ge__(self, "_BaseVersion" other)
bool __gt__(self, "_BaseVersion" other)
bool __ne__(self, object other)
Optional[Tuple[str, int]] _parse_letter_version(str letter, Union[str, bytes, SupportsInt] number)
LegacyCmpKey _legacy_cmpkey(str version)
Iterator[str] _parse_version_parts(str s)
Optional[LocalType] _parse_local_version(str local)
CmpKey _cmpkey(int epoch, Tuple[int,...] release, Optional[Tuple[str, int]] pre, Optional[Tuple[str, int]] post, Optional[Tuple[str, int]] dev, Optional[Tuple[SubLocalType]] local)