Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions news/10138.trivial.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Convert type commentaries to annotations on ``pip/_internal/models``.
9 changes: 3 additions & 6 deletions src/pip/_internal/models/candidate.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ class InstallationCandidate(KeyBasedCompareMixin):

__slots__ = ["name", "version", "link"]

def __init__(self, name, version, link):
# type: (str, str, Link) -> None
def __init__(self, name: str, version: str, link: Link) -> None:
self.name = name
self.version = parse_version(version)
self.link = link
Expand All @@ -21,14 +20,12 @@ def __init__(self, name, version, link):
defining_class=InstallationCandidate
)

def __repr__(self):
# type: () -> str
def __repr__(self) -> str:
return "<InstallationCandidate({!r}, {!r}, {!r})>".format(
self.name, self.version, self.link,
)

def __str__(self):
# type: () -> str
def __str__(self) -> str:
return '{!r} candidate (version {} at {})'.format(
self.name, self.version, self.link,
)
83 changes: 35 additions & 48 deletions src/pip/_internal/models/direct_url.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ class DirectUrlValidationError(Exception):
pass


def _get(d, expected_type, key, default=None):
# type: (Dict[str, Any], Type[T], str, Optional[T]) -> Optional[T]
def _get(
d: Dict[str, Any], expected_type: Type[T], key: str, default: Optional[T] = None
) -> Optional[T]:
"""Get value from dictionary and verify expected type."""
if key not in d:
return default
Expand All @@ -37,16 +38,16 @@ def _get(d, expected_type, key, default=None):
return value


def _get_required(d, expected_type, key, default=None):
# type: (Dict[str, Any], Type[T], str, Optional[T]) -> T
def _get_required(
d: Dict[str, Any], expected_type: Type[T], key: str, default: Optional[T] = None
) -> T:
value = _get(d, expected_type, key, default)
if value is None:
raise DirectUrlValidationError(f"{key} must have a value")
return value


def _exactly_one_of(infos):
# type: (Iterable[Optional[InfoType]]) -> InfoType
def _exactly_one_of(infos: Iterable[Optional["InfoType"]]) -> "InfoType":
infos = [info for info in infos if info is not None]
if not infos:
raise DirectUrlValidationError(
Expand All @@ -60,8 +61,7 @@ def _exactly_one_of(infos):
return infos[0]


def _filter_none(**kwargs):
# type: (Any) -> Dict[str, Any]
def _filter_none(**kwargs: Any) -> Dict[str, Any]:
"""Make dict excluding None values."""
return {k: v for k, v in kwargs.items() if v is not None}

Expand All @@ -71,21 +71,20 @@ class VcsInfo:

def __init__(
self,
vcs, # type: str
commit_id, # type: str
requested_revision=None, # type: Optional[str]
resolved_revision=None, # type: Optional[str]
resolved_revision_type=None, # type: Optional[str]
):
vcs: str,
commit_id: str,
requested_revision: Optional[str] = None,
resolved_revision: Optional[str] = None,
resolved_revision_type: Optional[str] = None,
) -> None:
self.vcs = vcs
self.requested_revision = requested_revision
self.commit_id = commit_id
self.resolved_revision = resolved_revision
self.resolved_revision_type = resolved_revision_type

@classmethod
def _from_dict(cls, d):
# type: (Optional[Dict[str, Any]]) -> Optional[VcsInfo]
def _from_dict(cls, d: Optional[Dict[str, Any]]) -> Optional["VcsInfo"]:
if d is None:
return None
return cls(
Expand All @@ -96,8 +95,7 @@ def _from_dict(cls, d):
resolved_revision_type=_get(d, str, "resolved_revision_type"),
)

def _to_dict(self):
# type: () -> Dict[str, Any]
def _to_dict(self) -> Dict[str, Any]:
return _filter_none(
vcs=self.vcs,
requested_revision=self.requested_revision,
Expand All @@ -112,19 +110,17 @@ class ArchiveInfo:

def __init__(
self,
hash=None, # type: Optional[str]
):
hash: Optional[str] = None,
) -> None:
self.hash = hash

@classmethod
def _from_dict(cls, d):
# type: (Optional[Dict[str, Any]]) -> Optional[ArchiveInfo]
def _from_dict(cls, d: Optional[Dict[str, Any]]) -> Optional["ArchiveInfo"]:
if d is None:
return None
return cls(hash=_get(d, str, "hash"))

def _to_dict(self):
# type: () -> Dict[str, Any]
def _to_dict(self) -> Dict[str, Any]:
return _filter_none(hash=self.hash)


Expand All @@ -133,21 +129,19 @@ class DirInfo:

def __init__(
self,
editable=False, # type: bool
):
editable: bool = False,
) -> None:
self.editable = editable

@classmethod
def _from_dict(cls, d):
# type: (Optional[Dict[str, Any]]) -> Optional[DirInfo]
def _from_dict(cls, d: Optional[Dict[str, Any]]) -> Optional["DirInfo"]:
if d is None:
return None
return cls(
editable=_get_required(d, bool, "editable", default=False)
)

def _to_dict(self):
# type: () -> Dict[str, Any]
def _to_dict(self) -> Dict[str, Any]:
return _filter_none(editable=self.editable or None)


Expand All @@ -158,16 +152,15 @@ class DirectUrl:

def __init__(
self,
url, # type: str
info, # type: InfoType
subdirectory=None, # type: Optional[str]
):
url: str,
info: InfoType,
subdirectory: Optional[str] = None,
) -> None:
self.url = url
self.info = info
self.subdirectory = subdirectory

def _remove_auth_from_netloc(self, netloc):
# type: (str) -> str
def _remove_auth_from_netloc(self, netloc: str) -> str:
if "@" not in netloc:
return netloc
user_pass, netloc_no_user_pass = netloc.split("@", 1)
Expand All @@ -182,8 +175,7 @@ def _remove_auth_from_netloc(self, netloc):
return netloc_no_user_pass

@property
def redacted_url(self):
# type: () -> str
def redacted_url(self) -> str:
"""url with user:password part removed unless it is formed with
environment variables as specified in PEP 610, or it is ``git``
in the case of a git URL.
Expand All @@ -195,13 +187,11 @@ def redacted_url(self):
)
return surl

def validate(self):
# type: () -> None
def validate(self) -> None:
self.from_dict(self.to_dict())

@classmethod
def from_dict(cls, d):
# type: (Dict[str, Any]) -> DirectUrl
def from_dict(cls, d: Dict[str, Any]) -> "DirectUrl":
return DirectUrl(
url=_get_required(d, str, "url"),
subdirectory=_get(d, str, "subdirectory"),
Expand All @@ -214,8 +204,7 @@ def from_dict(cls, d):
),
)

def to_dict(self):
# type: () -> Dict[str, Any]
def to_dict(self) -> Dict[str, Any]:
res = _filter_none(
url=self.redacted_url,
subdirectory=self.subdirectory,
Expand All @@ -224,10 +213,8 @@ def to_dict(self):
return res

@classmethod
def from_json(cls, s):
# type: (str) -> DirectUrl
def from_json(cls, s: str) -> "DirectUrl":
return cls.from_dict(json.loads(s))

def to_json(self):
# type: () -> str
def to_json(self) -> str:
return json.dumps(self.to_dict(), sort_keys=True)
22 changes: 10 additions & 12 deletions src/pip/_internal/models/format_control.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@ class FormatControl:

__slots__ = ["no_binary", "only_binary"]

def __init__(self, no_binary=None, only_binary=None):
# type: (Optional[Set[str]], Optional[Set[str]]) -> None
def __init__(
self,
no_binary: Optional[Set[str]] = None,
only_binary: Optional[Set[str]] = None
) -> None:
if no_binary is None:
no_binary = set()
if only_binary is None:
Expand All @@ -21,8 +24,7 @@ def __init__(self, no_binary=None, only_binary=None):
self.no_binary = no_binary
self.only_binary = only_binary

def __eq__(self, other):
# type: (object) -> bool
def __eq__(self, other: object) -> bool:
if not isinstance(other, self.__class__):
return NotImplemented

Expand All @@ -34,17 +36,15 @@ def __eq__(self, other):
for k in self.__slots__
)

def __repr__(self):
# type: () -> str
def __repr__(self) -> str:
return "{}({}, {})".format(
self.__class__.__name__,
self.no_binary,
self.only_binary
)

@staticmethod
def handle_mutual_excludes(value, target, other):
# type: (str, Set[str], Set[str]) -> None
def handle_mutual_excludes(value: str, target: Set[str], other: Set[str]) -> None:
if value.startswith('-'):
raise CommandError(
"--no-binary / --only-binary option requires 1 argument."
Expand All @@ -66,8 +66,7 @@ def handle_mutual_excludes(value, target, other):
other.discard(name)
target.add(name)

def get_allowed_formats(self, canonical_name):
# type: (str) -> FrozenSet[str]
def get_allowed_formats(self, canonical_name: str) -> FrozenSet[str]:
result = {"binary", "source"}
if canonical_name in self.only_binary:
result.discard('source')
Expand All @@ -79,8 +78,7 @@ def get_allowed_formats(self, canonical_name):
result.discard('binary')
return frozenset(result)

def disallow_binaries(self):
# type: () -> None
def disallow_binaries(self) -> None:
self.handle_mutual_excludes(
':all:', self.no_binary, self.only_binary,
)
6 changes: 2 additions & 4 deletions src/pip/_internal/models/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ class PackageIndex:
__slots__ = ['url', 'netloc', 'simple_url', 'pypi_url',
'file_storage_domain']

def __init__(self, url, file_storage_domain):
# type: (str, str) -> None
def __init__(self, url: str, file_storage_domain: str) -> None:
super().__init__()
self.url = url
self.netloc = urllib.parse.urlsplit(url).netloc
Expand All @@ -21,8 +20,7 @@ def __init__(self, url, file_storage_domain):
# block such packages themselves
self.file_storage_domain = file_storage_domain

def _url_for_path(self, path):
# type: (str) -> str
def _url_for_path(self, path: str) -> str:
return urllib.parse.urljoin(self.url, path)


Expand Down
Loading