Fullscreen eingestellt.

This commit is contained in:
2024-07-15 11:01:34 +02:00
parent 0c4926f0d5
commit a7955bc775
811 changed files with 9453 additions and 60540 deletions

View File

@@ -1,5 +1,6 @@
import collections
import logging
from dataclasses import dataclass
from typing import Generator, List, Optional, Sequence, Tuple
from pip._internal.utils.logging import indent_log
@@ -18,12 +19,9 @@ __all__ = [
logger = logging.getLogger(__name__)
@dataclass(frozen=True)
class InstallationResult:
def __init__(self, name: str) -> None:
self.name = name
def __repr__(self) -> str:
return f"InstallationResult(name={self.name!r})"
name: str
def _validate_requirements(

View File

@@ -12,6 +12,7 @@ import copy
import logging
import os
import re
from dataclasses import dataclass
from typing import Collection, Dict, List, Optional, Set, Tuple, Union
from pip._vendor.packaging.markers import Marker
@@ -132,8 +133,8 @@ def parse_editable(editable_req: str) -> Tuple[Optional[str], str, Set[str]]:
package_name = link.egg_fragment
if not package_name:
raise InstallationError(
"Could not detect requirement name for '{}', please specify one "
"with #egg=your_package_name".format(editable_req)
f"Could not detect requirement name for '{editable_req}', "
"please specify one with #egg=your_package_name"
)
return package_name, url, set()
@@ -191,18 +192,12 @@ def deduce_helpful_msg(req: str) -> str:
return msg
@dataclass(frozen=True)
class RequirementParts:
def __init__(
self,
requirement: Optional[Requirement],
link: Optional[Link],
markers: Optional[Marker],
extras: Set[str],
):
self.requirement = requirement
self.link = link
self.markers = markers
self.extras = extras
requirement: Optional[Requirement]
link: Optional[Link]
markers: Optional[Marker]
extras: Set[str]
def parse_req_from_editable(editable_req: str) -> RequirementParts:
@@ -211,8 +206,8 @@ def parse_req_from_editable(editable_req: str) -> RequirementParts:
if name is not None:
try:
req: Optional[Requirement] = Requirement(name)
except InvalidRequirement:
raise InstallationError(f"Invalid requirement: '{name}'")
except InvalidRequirement as exc:
raise InstallationError(f"Invalid requirement: {name!r}: {exc}")
else:
req = None
@@ -364,8 +359,8 @@ def parse_req_from_line(name: str, line_source: Optional[str]) -> RequirementPar
def _parse_req_string(req_as_string: str) -> Requirement:
try:
req = get_requirement(req_as_string)
except InvalidRequirement:
return get_requirement(req_as_string)
except InvalidRequirement as exc:
if os.path.sep in req_as_string:
add_msg = "It looks like a path."
add_msg += deduce_helpful_msg(req_as_string)
@@ -375,21 +370,10 @@ def parse_req_from_line(name: str, line_source: Optional[str]) -> RequirementPar
add_msg = "= is not a valid operator. Did you mean == ?"
else:
add_msg = ""
msg = with_source(f"Invalid requirement: {req_as_string!r}")
msg = with_source(f"Invalid requirement: {req_as_string!r}: {exc}")
if add_msg:
msg += f"\nHint: {add_msg}"
raise InstallationError(msg)
else:
# Deprecate extras after specifiers: "name>=1.0[extras]"
# This currently works by accident because _strip_extras() parses
# any extras in the end of the string and those are saved in
# RequirementParts
for spec in req.specifier:
spec_str = str(spec)
if spec_str.endswith("]"):
msg = f"Extras after version '{spec_str}'."
raise InstallationError(msg)
return req
if req_as_string is not None:
req: Optional[Requirement] = _parse_req_string(req_as_string)
@@ -445,8 +429,8 @@ def install_req_from_req_string(
) -> InstallRequirement:
try:
req = get_requirement(req_string)
except InvalidRequirement:
raise InstallationError(f"Invalid requirement: '{req_string}'")
except InvalidRequirement as exc:
raise InstallationError(f"Invalid requirement: {req_string!r}: {exc}")
domains_not_allowed = [
PyPI.file_storage_domain,

View File

@@ -17,6 +17,7 @@ from typing import (
Generator,
Iterable,
List,
NoReturn,
Optional,
Tuple,
)
@@ -24,17 +25,11 @@ from typing import (
from pip._internal.cli import cmdoptions
from pip._internal.exceptions import InstallationError, RequirementsFileParseError
from pip._internal.models.search_scope import SearchScope
from pip._internal.network.session import PipSession
from pip._internal.network.utils import raise_for_status
from pip._internal.utils.encoding import auto_decode
from pip._internal.utils.urls import get_url_scheme
if TYPE_CHECKING:
# NoReturn introduced in 3.6.2; imported only for type checking to maintain
# pip compatibility with older patch versions of Python 3.6
from typing import NoReturn
from pip._internal.index.package_finder import PackageFinder
from pip._internal.network.session import PipSession
__all__ = ["parse_requirements"]
@@ -136,7 +131,7 @@ class ParsedLine:
def parse_requirements(
filename: str,
session: PipSession,
session: "PipSession",
finder: Optional["PackageFinder"] = None,
options: Optional[optparse.Values] = None,
constraint: bool = False,
@@ -213,7 +208,7 @@ def handle_option_line(
lineno: int,
finder: Optional["PackageFinder"] = None,
options: Optional[optparse.Values] = None,
session: Optional[PipSession] = None,
session: Optional["PipSession"] = None,
) -> None:
if opts.hashes:
logger.warning(
@@ -281,7 +276,7 @@ def handle_line(
line: ParsedLine,
options: Optional[optparse.Values] = None,
finder: Optional["PackageFinder"] = None,
session: Optional[PipSession] = None,
session: Optional["PipSession"] = None,
) -> Optional[ParsedRequirement]:
"""Handle a single parsed requirements line; This can result in
creating/yielding requirements, or updating the finder.
@@ -324,7 +319,7 @@ def handle_line(
class RequirementsFileParser:
def __init__(
self,
session: PipSession,
session: "PipSession",
line_parser: LineParser,
) -> None:
self._session = session
@@ -529,7 +524,7 @@ def expand_env_variables(lines_enum: ReqFileLines) -> ReqFileLines:
yield line_number, line
def get_file_content(url: str, session: PipSession) -> Tuple[str, str]:
def get_file_content(url: str, session: "PipSession") -> Tuple[str, str]:
"""Gets the content of a file; it may be a filename, file: URL, or
http: URL. Returns (location, content). Content is unicode.
Respects # -*- coding: declarations on the retrieved files.
@@ -537,10 +532,12 @@ def get_file_content(url: str, session: PipSession) -> Tuple[str, str]:
:param url: File path or url.
:param session: PipSession instance.
"""
scheme = get_url_scheme(url)
scheme = urllib.parse.urlsplit(url).scheme
# Pip has special support for file:// URLs (LocalFSAdapter).
if scheme in ["http", "https", "file"]:
# Delay importing heavy network modules until absolutely necessary.
from pip._internal.network.utils import raise_for_status
resp = session.get(url)
raise_for_status(resp)
return resp.url, resp.text

View File

@@ -52,7 +52,6 @@ from pip._internal.utils.misc import (
redact_auth_from_requirement,
redact_auth_from_url,
)
from pip._internal.utils.packaging import safe_extra
from pip._internal.utils.subprocess import runner_with_spinner_message
from pip._internal.utils.temp_dir import TempDirectory, tempdir_kinds
from pip._internal.utils.unpacking import unpack_file
@@ -222,8 +221,9 @@ class InstallRequirement:
return s
def __repr__(self) -> str:
return "<{} object: {} editable={!r}>".format(
self.__class__.__name__, str(self), self.editable
return (
f"<{self.__class__.__name__} object: "
f"{str(self)} editable={self.editable!r}>"
)
def format_debug(self) -> str:
@@ -244,7 +244,7 @@ class InstallRequirement:
return None
return self.req.name
@functools.lru_cache() # use cached_property in python 3.8+
@functools.cached_property
def supports_pyproject_editable(self) -> bool:
if not self.use_pep517:
return False
@@ -283,12 +283,7 @@ class InstallRequirement:
extras_requested = ("",)
if self.markers is not None:
return any(
self.markers.evaluate({"extra": extra})
# TODO: Remove these two variants when packaging is upgraded to
# support the marker comparison logic specified in PEP 685.
or self.markers.evaluate({"extra": safe_extra(extra)})
or self.markers.evaluate({"extra": canonicalize_name(extra)})
for extra in extras_requested
self.markers.evaluate({"extra": extra}) for extra in extras_requested
)
else:
return True
@@ -542,7 +537,7 @@ class InstallRequirement:
if (
self.editable
and self.use_pep517
and not self.supports_pyproject_editable()
and not self.supports_pyproject_editable
and not os.path.isfile(self.setup_py_path)
and not os.path.isfile(self.setup_cfg_path)
):
@@ -568,7 +563,7 @@ class InstallRequirement:
if (
self.editable
and self.permit_editable_wheels
and self.supports_pyproject_editable()
and self.supports_pyproject_editable
):
self.metadata_directory = generate_editable_metadata(
build_env=self.build_env,

View File

@@ -2,12 +2,9 @@ import logging
from collections import OrderedDict
from typing import Dict, List
from pip._vendor.packaging.specifiers import LegacySpecifier
from pip._vendor.packaging.utils import canonicalize_name
from pip._vendor.packaging.version import LegacyVersion
from pip._internal.req.req_install import InstallRequirement
from pip._internal.utils.deprecation import deprecated
logger = logging.getLogger(__name__)
@@ -83,37 +80,3 @@ class RequirementSet:
for install_req in self.all_requirements
if not install_req.constraint and not install_req.satisfied_by
]
def warn_legacy_versions_and_specifiers(self) -> None:
for req in self.requirements_to_install:
version = req.get_dist().version
if isinstance(version, LegacyVersion):
deprecated(
reason=(
f"pip has selected the non standard version {version} "
f"of {req}. In the future this version will be "
f"ignored as it isn't standard compliant."
),
replacement=(
"set or update constraints to select another version "
"or contact the package author to fix the version number"
),
issue=12063,
gone_in="24.1",
)
for dep in req.get_dist().iter_dependencies():
if any(isinstance(spec, LegacySpecifier) for spec in dep.specifier):
deprecated(
reason=(
f"pip has selected {req} {version} which has non "
f"standard dependency specifier {dep}. "
f"In the future this version of {req} will be "
f"ignored as it isn't standard compliant."
),
replacement=(
"set or update constraints to select another version "
"or contact the package author to fix the version number"
),
issue=12063,
gone_in="24.1",
)

View File

@@ -5,7 +5,7 @@ import sysconfig
from importlib.util import cache_from_source
from typing import Any, Callable, Dict, Generator, Iterable, List, Optional, Set, Tuple
from pip._internal.exceptions import UninstallationError
from pip._internal.exceptions import LegacyDistutilsInstall, UninstallMissingRecord
from pip._internal.locations import get_bin_prefix, get_bin_user
from pip._internal.metadata import BaseDistribution
from pip._internal.utils.compat import WINDOWS
@@ -61,7 +61,7 @@ def uninstallation_paths(dist: BaseDistribution) -> Generator[str, None, None]:
UninstallPathSet.add() takes care of the __pycache__ .py[co].
If RECORD is not found, raises UninstallationError,
If RECORD is not found, raises an error,
with possible information from the INSTALLER file.
https://packaging.python.org/specifications/recording-installed-packages/
@@ -71,17 +71,7 @@ def uninstallation_paths(dist: BaseDistribution) -> Generator[str, None, None]:
entries = dist.iter_declared_entries()
if entries is None:
msg = f"Cannot uninstall {dist}, RECORD file not found."
installer = dist.installer
if not installer or installer == "pip":
dep = f"{dist.raw_name}=={dist.version}"
msg += (
" You might be able to recover from this via: "
f"'pip install --force-reinstall --no-deps {dep}'."
)
else:
msg += f" Hint: The package was installed by {installer}."
raise UninstallationError(msg)
raise UninstallMissingRecord(distribution=dist)
for entry in entries:
path = os.path.join(location, entry)
@@ -315,7 +305,7 @@ class UninstallPathSet:
# Create local cache of normalize_path results. Creating an UninstallPathSet
# can result in hundreds/thousands of redundant calls to normalize_path with
# the same args, which hurts performance.
self._normalize_path_cached = functools.lru_cache()(normalize_path)
self._normalize_path_cached = functools.lru_cache(normalize_path)
def _permitted(self, path: str) -> bool:
"""
@@ -367,7 +357,7 @@ class UninstallPathSet:
)
return
dist_name_version = f"{self._dist.raw_name}-{self._dist.version}"
dist_name_version = f"{self._dist.raw_name}-{self._dist.raw_version}"
logger.info("Uninstalling %s:", dist_name_version)
with indent_log():
@@ -509,13 +499,7 @@ class UninstallPathSet:
paths_to_remove.add(f"{path}.pyo")
elif dist.installed_by_distutils:
raise UninstallationError(
"Cannot uninstall {!r}. It is a distutils installed project "
"and thus we cannot accurately determine which files belong "
"to it which would lead to only a partial uninstall.".format(
dist.raw_name,
)
)
raise LegacyDistutilsInstall(distribution=dist)
elif dist.installed_as_egg:
# package installed by easy_install