mirror of https://github.com/pypa/pip
Use strict optional checking in req_install.py (#11379)
* Use strict optional checking in req_install.py Suggested by pradyunsg in #11374 Since half of the API of this class depends on self.req not being None, it seems like we should just prevent users from passing None here. However, I wasn't able to make that change. Rather than sprinkle asserts everywhere, I added "checked" properties. I find this less ad hoc and easier to adapt if e.g. we're able to make self.req never None in the future. There are now some code paths where we have asserts that we didn't before. I relied on other type hints in pip's code base to be accurate. If that is not the case and we actually relied on some function being able to accept None when not typed as such, we may hit these asserts. But hopefully tests would catch such a thing. * news * black * inline asserts * code review * fix up merge issue * fix specifier bug
This commit is contained in:
parent
3c0147a889
commit
a19ade74a5
|
@ -1,6 +1,3 @@
|
|||
# The following comment should be removed at some point in the future.
|
||||
# mypy: strict-optional=False
|
||||
|
||||
import functools
|
||||
import logging
|
||||
import os
|
||||
|
@ -244,6 +241,7 @@ class InstallRequirement:
|
|||
|
||||
@property
|
||||
def specifier(self) -> SpecifierSet:
|
||||
assert self.req is not None
|
||||
return self.req.specifier
|
||||
|
||||
@property
|
||||
|
@ -257,7 +255,8 @@ class InstallRequirement:
|
|||
|
||||
For example, some-package==1.2 is pinned; some-package>1.2 is not.
|
||||
"""
|
||||
specifiers = self.specifier
|
||||
assert self.req is not None
|
||||
specifiers = self.req.specifier
|
||||
return len(specifiers) == 1 and next(iter(specifiers)).operator in {"==", "==="}
|
||||
|
||||
def match_markers(self, extras_requested: Optional[Iterable[str]] = None) -> bool:
|
||||
|
@ -305,6 +304,7 @@ class InstallRequirement:
|
|||
else:
|
||||
link = None
|
||||
if link and link.hash:
|
||||
assert link.hash_name is not None
|
||||
good_hashes.setdefault(link.hash_name, []).append(link.hash)
|
||||
return Hashes(good_hashes)
|
||||
|
||||
|
@ -314,6 +314,7 @@ class InstallRequirement:
|
|||
return None
|
||||
s = str(self.req)
|
||||
if self.comes_from:
|
||||
comes_from: Optional[str]
|
||||
if isinstance(self.comes_from, str):
|
||||
comes_from = self.comes_from
|
||||
else:
|
||||
|
@ -345,7 +346,7 @@ class InstallRequirement:
|
|||
|
||||
# When parallel builds are enabled, add a UUID to the build directory
|
||||
# name so multiple builds do not interfere with each other.
|
||||
dir_name: str = canonicalize_name(self.name)
|
||||
dir_name: str = canonicalize_name(self.req.name)
|
||||
if parallel_builds:
|
||||
dir_name = f"{dir_name}_{uuid.uuid4().hex}"
|
||||
|
||||
|
@ -388,6 +389,7 @@ class InstallRequirement:
|
|||
)
|
||||
|
||||
def warn_on_mismatching_name(self) -> None:
|
||||
assert self.req is not None
|
||||
metadata_name = canonicalize_name(self.metadata["Name"])
|
||||
if canonicalize_name(self.req.name) == metadata_name:
|
||||
# Everything is fine.
|
||||
|
@ -457,6 +459,7 @@ class InstallRequirement:
|
|||
# Things valid for sdists
|
||||
@property
|
||||
def unpacked_source_directory(self) -> str:
|
||||
assert self.source_dir, f"No source dir for {self}"
|
||||
return os.path.join(
|
||||
self.source_dir, self.link and self.link.subdirectory_fragment or ""
|
||||
)
|
||||
|
@ -543,7 +546,7 @@ class InstallRequirement:
|
|||
Under PEP 517 and PEP 660, call the backend hook to prepare the metadata.
|
||||
Under legacy processing, call setup.py egg-info.
|
||||
"""
|
||||
assert self.source_dir
|
||||
assert self.source_dir, f"No source dir for {self}"
|
||||
details = self.name or f"from {self.link}"
|
||||
|
||||
if self.use_pep517:
|
||||
|
@ -592,8 +595,10 @@ class InstallRequirement:
|
|||
if self.metadata_directory:
|
||||
return get_directory_distribution(self.metadata_directory)
|
||||
elif self.local_file_path and self.is_wheel:
|
||||
assert self.req is not None
|
||||
return get_wheel_distribution(
|
||||
FilesystemWheel(self.local_file_path), canonicalize_name(self.name)
|
||||
FilesystemWheel(self.local_file_path),
|
||||
canonicalize_name(self.req.name),
|
||||
)
|
||||
raise AssertionError(
|
||||
f"InstallRequirement {self} has no metadata directory and no wheel: "
|
||||
|
@ -601,9 +606,9 @@ class InstallRequirement:
|
|||
)
|
||||
|
||||
def assert_source_matches_version(self) -> None:
|
||||
assert self.source_dir
|
||||
assert self.source_dir, f"No source dir for {self}"
|
||||
version = self.metadata["version"]
|
||||
if self.req.specifier and version not in self.req.specifier:
|
||||
if self.req and self.req.specifier and version not in self.req.specifier:
|
||||
logger.warning(
|
||||
"Requested %s, but installing version %s",
|
||||
self,
|
||||
|
@ -696,9 +701,10 @@ class InstallRequirement:
|
|||
name = name.replace(os.path.sep, "/")
|
||||
return name
|
||||
|
||||
assert self.req is not None
|
||||
path = os.path.join(parentdir, path)
|
||||
name = _clean_zip_name(path, rootdir)
|
||||
return self.name + "/" + name
|
||||
return self.req.name + "/" + name
|
||||
|
||||
def archive(self, build_dir: Optional[str]) -> None:
|
||||
"""Saves archive to provided build_dir.
|
||||
|
@ -777,8 +783,9 @@ class InstallRequirement:
|
|||
use_user_site: bool = False,
|
||||
pycompile: bool = True,
|
||||
) -> None:
|
||||
assert self.req is not None
|
||||
scheme = get_scheme(
|
||||
self.name,
|
||||
self.req.name,
|
||||
user=use_user_site,
|
||||
home=home,
|
||||
root=root,
|
||||
|
@ -792,7 +799,7 @@ class InstallRequirement:
|
|||
prefix=prefix,
|
||||
home=home,
|
||||
use_user_site=use_user_site,
|
||||
name=self.name,
|
||||
name=self.req.name,
|
||||
setup_py_path=self.setup_py_path,
|
||||
isolated=self.isolated,
|
||||
build_env=self.build_env,
|
||||
|
@ -805,7 +812,7 @@ class InstallRequirement:
|
|||
assert self.local_file_path
|
||||
|
||||
install_wheel(
|
||||
self.name,
|
||||
self.req.name,
|
||||
self.local_file_path,
|
||||
scheme=scheme,
|
||||
req_description=str(self.req),
|
||||
|
|
Loading…
Reference in New Issue