Skip to content

Commit

Permalink
Add types for packaging.version._Version (#665)
Browse files Browse the repository at this point in the history
This makes interactions with the internal _version object type safe,
instead of having them all resolve to Any.
  • Loading branch information
hauntsaninja committed Jun 16, 2023
1 parent fe8f0bb commit f8893d4
Showing 1 changed file with 28 additions and 29 deletions.
57 changes: 28 additions & 29 deletions src/packaging/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,37 +7,39 @@
from packaging.version import parse, Version
"""

import collections
import itertools
import re
from typing import Any, Callable, Optional, SupportsInt, Tuple, Union
from typing import Any, Callable, NamedTuple, Optional, SupportsInt, Tuple, Union

from ._structures import Infinity, InfinityType, NegativeInfinity, NegativeInfinityType

__all__ = ["VERSION_PATTERN", "parse", "Version", "InvalidVersion"]

InfiniteTypes = Union[InfinityType, NegativeInfinityType]
PrePostDevType = Union[InfiniteTypes, Tuple[str, int]]
SubLocalType = Union[InfiniteTypes, int, str]
LocalType = Union[
LocalType = Tuple[Union[int, str], ...]

CmpPrePostDevType = Union[InfinityType, NegativeInfinityType, Tuple[str, int]]
CmpLocalType = Union[
NegativeInfinityType,
Tuple[
Union[
SubLocalType,
Tuple[SubLocalType, str],
Tuple[NegativeInfinityType, SubLocalType],
],
...,
],
Tuple[Union[Tuple[int, str], Tuple[NegativeInfinityType, Union[int, str]]], ...],
]
CmpKey = Tuple[
int, Tuple[int, ...], PrePostDevType, PrePostDevType, PrePostDevType, LocalType
int,
Tuple[int, ...],
CmpPrePostDevType,
CmpPrePostDevType,
CmpPrePostDevType,
CmpLocalType,
]
VersionComparisonMethod = Callable[[CmpKey, CmpKey], bool]

_Version = collections.namedtuple(
"_Version", ["epoch", "release", "dev", "pre", "post", "local"]
)

class _Version(NamedTuple):
epoch: int
release: Tuple[int, ...]
dev: Optional[Tuple[str, int]]
pre: Optional[Tuple[str, int]]
post: Optional[Tuple[str, int]]
local: Optional[LocalType]


def parse(version: str) -> "Version":
Expand Down Expand Up @@ -269,8 +271,7 @@ def epoch(self) -> int:
>>> Version("1!2.0.0").epoch
1
"""
_epoch: int = self._version.epoch
return _epoch
return self._version.epoch

@property
def release(self) -> Tuple[int, ...]:
Expand All @@ -286,8 +287,7 @@ def release(self) -> Tuple[int, ...]:
Includes trailing zeroes but not the epoch or any pre-release / development /
post-release suffixes.
"""
_release: Tuple[int, ...] = self._version.release
return _release
return self._version.release

@property
def pre(self) -> Optional[Tuple[str, int]]:
Expand All @@ -302,8 +302,7 @@ def pre(self) -> Optional[Tuple[str, int]]:
>>> Version("1.2.3rc1").pre
('rc', 1)
"""
_pre: Optional[Tuple[str, int]] = self._version.pre
return _pre
return self._version.pre

@property
def post(self) -> Optional[int]:
Expand Down Expand Up @@ -507,7 +506,7 @@ def _cmpkey(
pre: Optional[Tuple[str, int]],
post: Optional[Tuple[str, int]],
dev: Optional[Tuple[str, int]],
local: Optional[Tuple[SubLocalType]],
local: Optional[LocalType],
) -> CmpKey:

# When we compare a release version, we want to compare it with all of the
Expand All @@ -524,7 +523,7 @@ def _cmpkey(
# if there is not a pre or a post segment. If we have one of those then
# the normal sorting rules will handle this case correctly.
if pre is None and post is None and dev is not None:
_pre: PrePostDevType = NegativeInfinity
_pre: CmpPrePostDevType = NegativeInfinity
# Versions without a pre-release (except as noted above) should sort after
# those with one.
elif pre is None:
Expand All @@ -534,21 +533,21 @@ def _cmpkey(

# Versions without a post segment should sort before those with one.
if post is None:
_post: PrePostDevType = NegativeInfinity
_post: CmpPrePostDevType = NegativeInfinity

else:
_post = post

# Versions without a development segment should sort after those with one.
if dev is None:
_dev: PrePostDevType = Infinity
_dev: CmpPrePostDevType = Infinity

else:
_dev = dev

if local is None:
# Versions without a local segment should sort before those with one.
_local: LocalType = NegativeInfinity
_local: CmpLocalType = NegativeInfinity
else:
# Versions with a local segment need that segment parsed to implement
# the sorting rules in PEP440.
Expand Down

0 comments on commit f8893d4

Please sign in to comment.