Voice et bot modif
This commit is contained in:
parent
189d56026b
commit
7333a22bcd
10774 changed files with 634644 additions and 933308 deletions
|
|
@ -5,8 +5,6 @@ operate. This is expected to be importable from any/all files within the
|
|||
subpackage and, thus, should not depend on them.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import configparser
|
||||
import contextlib
|
||||
import locale
|
||||
|
|
@ -14,23 +12,19 @@ import logging
|
|||
import pathlib
|
||||
import re
|
||||
import sys
|
||||
from collections.abc import Iterator
|
||||
from itertools import chain, groupby, repeat
|
||||
from typing import TYPE_CHECKING, Literal
|
||||
from typing import TYPE_CHECKING, Dict, Iterator, List, Optional, Union
|
||||
|
||||
from pip._vendor.packaging.requirements import InvalidRequirement
|
||||
from pip._vendor.packaging.version import InvalidVersion
|
||||
from pip._vendor.requests.models import Request, Response
|
||||
from pip._vendor.rich.console import Console, ConsoleOptions, RenderResult
|
||||
from pip._vendor.rich.markup import escape
|
||||
from pip._vendor.rich.text import Text
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from hashlib import _Hash
|
||||
|
||||
from pip._vendor.requests.models import Request, Response
|
||||
from typing import Literal
|
||||
|
||||
from pip._internal.metadata import BaseDistribution
|
||||
from pip._internal.network.download import _FileDownload
|
||||
from pip._internal.req.req_install import InstallRequirement
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
|
@ -44,7 +38,7 @@ def _is_kebab_case(s: str) -> bool:
|
|||
|
||||
|
||||
def _prefix_with_indent(
|
||||
s: Text | str,
|
||||
s: Union[Text, str],
|
||||
console: Console,
|
||||
*,
|
||||
prefix: str,
|
||||
|
|
@ -80,13 +74,13 @@ class DiagnosticPipError(PipError):
|
|||
def __init__(
|
||||
self,
|
||||
*,
|
||||
kind: Literal["error", "warning"] = "error",
|
||||
reference: str | None = None,
|
||||
message: str | Text,
|
||||
context: str | Text | None,
|
||||
hint_stmt: str | Text | None,
|
||||
note_stmt: str | Text | None = None,
|
||||
link: str | None = None,
|
||||
kind: 'Literal["error", "warning"]' = "error",
|
||||
reference: Optional[str] = None,
|
||||
message: Union[str, Text],
|
||||
context: Optional[Union[str, Text]],
|
||||
hint_stmt: Optional[Union[str, Text]],
|
||||
note_stmt: Optional[Union[str, Text]] = None,
|
||||
link: Optional[str] = None,
|
||||
) -> None:
|
||||
# Ensure a proper reference is provided.
|
||||
if reference is None:
|
||||
|
|
@ -190,21 +184,8 @@ class InstallationError(PipError):
|
|||
"""General exception during installation"""
|
||||
|
||||
|
||||
class FailedToPrepareCandidate(InstallationError):
|
||||
"""Raised when we fail to prepare a candidate (i.e. fetch and generate metadata).
|
||||
|
||||
This is intentionally not a diagnostic error, since the output will be presented
|
||||
above this error, when this occurs. This should instead present information to the
|
||||
user.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self, *, package_name: str, requirement_chain: str, failed_step: str
|
||||
) -> None:
|
||||
super().__init__(f"Failed to build '{package_name}' when {failed_step.lower()}")
|
||||
self.package_name = package_name
|
||||
self.requirement_chain = requirement_chain
|
||||
self.failed_step = failed_step
|
||||
class UninstallationError(PipError):
|
||||
"""General exception during uninstallation"""
|
||||
|
||||
|
||||
class MissingPyProjectBuildRequires(DiagnosticPipError):
|
||||
|
|
@ -252,7 +233,7 @@ class NoneMetadataError(PipError):
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
dist: BaseDistribution,
|
||||
dist: "BaseDistribution",
|
||||
metadata_name: str,
|
||||
) -> None:
|
||||
"""
|
||||
|
|
@ -313,8 +294,8 @@ class NetworkConnectionError(PipError):
|
|||
def __init__(
|
||||
self,
|
||||
error_msg: str,
|
||||
response: Response | None = None,
|
||||
request: Request | None = None,
|
||||
response: Optional[Response] = None,
|
||||
request: Optional[Request] = None,
|
||||
) -> None:
|
||||
"""
|
||||
Initialize NetworkConnectionError with `request` and `response`
|
||||
|
|
@ -363,7 +344,7 @@ class MetadataInconsistent(InstallationError):
|
|||
"""
|
||||
|
||||
def __init__(
|
||||
self, ireq: InstallRequirement, field: str, f_val: str, m_val: str
|
||||
self, ireq: "InstallRequirement", field: str, f_val: str, m_val: str
|
||||
) -> None:
|
||||
self.ireq = ireq
|
||||
self.field = field
|
||||
|
|
@ -377,17 +358,6 @@ class MetadataInconsistent(InstallationError):
|
|||
)
|
||||
|
||||
|
||||
class MetadataInvalid(InstallationError):
|
||||
"""Metadata is invalid."""
|
||||
|
||||
def __init__(self, ireq: InstallRequirement, error: str) -> None:
|
||||
self.ireq = ireq
|
||||
self.error = error
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"Requested {self.ireq} has invalid metadata: {self.error}"
|
||||
|
||||
|
||||
class InstallationSubprocessError(DiagnosticPipError, InstallationError):
|
||||
"""A subprocess call failed."""
|
||||
|
||||
|
|
@ -398,10 +368,10 @@ class InstallationSubprocessError(DiagnosticPipError, InstallationError):
|
|||
*,
|
||||
command_description: str,
|
||||
exit_code: int,
|
||||
output_lines: list[str] | None,
|
||||
output_lines: Optional[List[str]],
|
||||
) -> None:
|
||||
if output_lines is None:
|
||||
output_prompt = Text("No available output.")
|
||||
output_prompt = Text("See above for output.")
|
||||
else:
|
||||
output_prompt = (
|
||||
Text.from_markup(f"[red][{len(output_lines)} lines of output][/]\n")
|
||||
|
|
@ -429,7 +399,7 @@ class InstallationSubprocessError(DiagnosticPipError, InstallationError):
|
|||
return f"{self.command_description} exited with {self.exit_code}"
|
||||
|
||||
|
||||
class MetadataGenerationFailed(DiagnosticPipError, InstallationError):
|
||||
class MetadataGenerationFailed(InstallationSubprocessError, InstallationError):
|
||||
reference = "metadata-generation-failed"
|
||||
|
||||
def __init__(
|
||||
|
|
@ -437,7 +407,7 @@ class MetadataGenerationFailed(DiagnosticPipError, InstallationError):
|
|||
*,
|
||||
package_details: str,
|
||||
) -> None:
|
||||
super().__init__(
|
||||
super(InstallationSubprocessError, self).__init__(
|
||||
message="Encountered error while generating package metadata.",
|
||||
context=escape(package_details),
|
||||
hint_stmt="See above for details.",
|
||||
|
|
@ -452,9 +422,9 @@ class HashErrors(InstallationError):
|
|||
"""Multiple HashError instances rolled into one for reporting"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.errors: list[HashError] = []
|
||||
self.errors: List["HashError"] = []
|
||||
|
||||
def append(self, error: HashError) -> None:
|
||||
def append(self, error: "HashError") -> None:
|
||||
self.errors.append(error)
|
||||
|
||||
def __str__(self) -> str:
|
||||
|
|
@ -488,7 +458,7 @@ class HashError(InstallationError):
|
|||
|
||||
"""
|
||||
|
||||
req: InstallRequirement | None = None
|
||||
req: Optional["InstallRequirement"] = None
|
||||
head = ""
|
||||
order: int = -1
|
||||
|
||||
|
|
@ -610,7 +580,7 @@ class HashMismatch(HashError):
|
|||
"someone may have tampered with them."
|
||||
)
|
||||
|
||||
def __init__(self, allowed: dict[str, list[str]], gots: dict[str, _Hash]) -> None:
|
||||
def __init__(self, allowed: Dict[str, List[str]], gots: Dict[str, "_Hash"]) -> None:
|
||||
"""
|
||||
:param allowed: A dict of algorithm names pointing to lists of allowed
|
||||
hex digests
|
||||
|
|
@ -635,12 +605,12 @@ class HashMismatch(HashError):
|
|||
|
||||
"""
|
||||
|
||||
def hash_then_or(hash_name: str) -> chain[str]:
|
||||
def hash_then_or(hash_name: str) -> "chain[str]":
|
||||
# For now, all the decent hashes have 6-char names, so we can get
|
||||
# away with hard-coding space literals.
|
||||
return chain([hash_name], repeat(" or"))
|
||||
|
||||
lines: list[str] = []
|
||||
lines: List[str] = []
|
||||
for hash_name, expecteds in self.allowed.items():
|
||||
prefix = hash_then_or(hash_name)
|
||||
lines.extend((f" Expected {next(prefix)} {e}") for e in expecteds)
|
||||
|
|
@ -661,8 +631,8 @@ class ConfigurationFileCouldNotBeLoaded(ConfigurationError):
|
|||
def __init__(
|
||||
self,
|
||||
reason: str = "could not be loaded",
|
||||
fname: str | None = None,
|
||||
error: configparser.Error | None = None,
|
||||
fname: Optional[str] = None,
|
||||
error: Optional[configparser.Error] = None,
|
||||
) -> None:
|
||||
super().__init__(error)
|
||||
self.reason = reason
|
||||
|
|
@ -697,7 +667,7 @@ class ExternallyManagedEnvironment(DiagnosticPipError):
|
|||
|
||||
reference = "externally-managed-environment"
|
||||
|
||||
def __init__(self, error: str | None) -> None:
|
||||
def __init__(self, error: Optional[str]) -> None:
|
||||
if error is None:
|
||||
context = Text(_DEFAULT_EXTERNALLY_MANAGED_ERROR)
|
||||
else:
|
||||
|
|
@ -724,7 +694,7 @@ class ExternallyManagedEnvironment(DiagnosticPipError):
|
|||
try:
|
||||
category = locale.LC_MESSAGES
|
||||
except AttributeError:
|
||||
lang: str | None = None
|
||||
lang: Optional[str] = None
|
||||
else:
|
||||
lang, _ = locale.getlocale(category)
|
||||
if lang is not None:
|
||||
|
|
@ -739,8 +709,8 @@ class ExternallyManagedEnvironment(DiagnosticPipError):
|
|||
@classmethod
|
||||
def from_config(
|
||||
cls,
|
||||
config: pathlib.Path | str,
|
||||
) -> ExternallyManagedEnvironment:
|
||||
config: Union[pathlib.Path, str],
|
||||
) -> "ExternallyManagedEnvironment":
|
||||
parser = configparser.ConfigParser(interpolation=None)
|
||||
try:
|
||||
parser.read(config, encoding="utf-8")
|
||||
|
|
@ -756,143 +726,3 @@ class ExternallyManagedEnvironment(DiagnosticPipError):
|
|||
exc_info = logger.isEnabledFor(VERBOSE)
|
||||
logger.warning("Failed to read %s", config, exc_info=exc_info)
|
||||
return cls(None)
|
||||
|
||||
|
||||
class UninstallMissingRecord(DiagnosticPipError):
|
||||
reference = "uninstall-no-record-file"
|
||||
|
||||
def __init__(self, *, distribution: BaseDistribution) -> None:
|
||||
installer = distribution.installer
|
||||
if not installer or installer == "pip":
|
||||
dep = f"{distribution.raw_name}=={distribution.version}"
|
||||
hint = Text.assemble(
|
||||
"You might be able to recover from this via: ",
|
||||
(f"pip install --force-reinstall --no-deps {dep}", "green"),
|
||||
)
|
||||
else:
|
||||
hint = Text(
|
||||
f"The package was installed by {installer}. "
|
||||
"You should check if it can uninstall the package."
|
||||
)
|
||||
|
||||
super().__init__(
|
||||
message=Text(f"Cannot uninstall {distribution}"),
|
||||
context=(
|
||||
"The package's contents are unknown: "
|
||||
f"no RECORD file was found for {distribution.raw_name}."
|
||||
),
|
||||
hint_stmt=hint,
|
||||
)
|
||||
|
||||
|
||||
class LegacyDistutilsInstall(DiagnosticPipError):
|
||||
reference = "uninstall-distutils-installed-package"
|
||||
|
||||
def __init__(self, *, distribution: BaseDistribution) -> None:
|
||||
super().__init__(
|
||||
message=Text(f"Cannot uninstall {distribution}"),
|
||||
context=(
|
||||
"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."
|
||||
),
|
||||
hint_stmt=None,
|
||||
)
|
||||
|
||||
|
||||
class InvalidInstalledPackage(DiagnosticPipError):
|
||||
reference = "invalid-installed-package"
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
dist: BaseDistribution,
|
||||
invalid_exc: InvalidRequirement | InvalidVersion,
|
||||
) -> None:
|
||||
installed_location = dist.installed_location
|
||||
|
||||
if isinstance(invalid_exc, InvalidRequirement):
|
||||
invalid_type = "requirement"
|
||||
else:
|
||||
invalid_type = "version"
|
||||
|
||||
super().__init__(
|
||||
message=Text(
|
||||
f"Cannot process installed package {dist} "
|
||||
+ (f"in {installed_location!r} " if installed_location else "")
|
||||
+ f"because it has an invalid {invalid_type}:\n{invalid_exc.args[0]}"
|
||||
),
|
||||
context=(
|
||||
"Starting with pip 24.1, packages with invalid "
|
||||
f"{invalid_type}s can not be processed."
|
||||
),
|
||||
hint_stmt="To proceed this package must be uninstalled.",
|
||||
)
|
||||
|
||||
|
||||
class IncompleteDownloadError(DiagnosticPipError):
|
||||
"""Raised when the downloader receives fewer bytes than advertised
|
||||
in the Content-Length header."""
|
||||
|
||||
reference = "incomplete-download"
|
||||
|
||||
def __init__(self, download: _FileDownload) -> None:
|
||||
# Dodge circular import.
|
||||
from pip._internal.utils.misc import format_size
|
||||
|
||||
assert download.size is not None
|
||||
download_status = (
|
||||
f"{format_size(download.bytes_received)}/{format_size(download.size)}"
|
||||
)
|
||||
if download.reattempts:
|
||||
retry_status = f"after {download.reattempts + 1} attempts "
|
||||
hint = "Use --resume-retries to configure resume attempt limit."
|
||||
else:
|
||||
# Download retrying is not enabled.
|
||||
retry_status = ""
|
||||
hint = "Consider using --resume-retries to enable download resumption."
|
||||
message = Text(
|
||||
f"Download failed {retry_status}because not enough bytes "
|
||||
f"were received ({download_status})"
|
||||
)
|
||||
|
||||
super().__init__(
|
||||
message=message,
|
||||
context=f"URL: {download.link.redacted_url}",
|
||||
hint_stmt=hint,
|
||||
note_stmt="This is an issue with network connectivity, not pip.",
|
||||
)
|
||||
|
||||
|
||||
class ResolutionTooDeepError(DiagnosticPipError):
|
||||
"""Raised when the dependency resolver exceeds the maximum recursion depth."""
|
||||
|
||||
reference = "resolution-too-deep"
|
||||
|
||||
def __init__(self) -> None:
|
||||
super().__init__(
|
||||
message="Dependency resolution exceeded maximum depth",
|
||||
context=(
|
||||
"Pip cannot resolve the current dependencies as the dependency graph "
|
||||
"is too complex for pip to solve efficiently."
|
||||
),
|
||||
hint_stmt=(
|
||||
"Try adding lower bounds to constrain your dependencies, "
|
||||
"for example: 'package>=2.0.0' instead of just 'package'. "
|
||||
),
|
||||
link="https://pip.pypa.io/en/stable/topics/dependency-resolution/#handling-resolution-too-deep-errors",
|
||||
)
|
||||
|
||||
|
||||
class InstallWheelBuildError(DiagnosticPipError):
|
||||
reference = "failed-wheel-build-for-install"
|
||||
|
||||
def __init__(self, failed: list[InstallRequirement]) -> None:
|
||||
super().__init__(
|
||||
message=(
|
||||
"Failed to build installable wheels for some "
|
||||
"pyproject.toml based projects"
|
||||
),
|
||||
context=", ".join(r.name for r in failed), # type: ignore
|
||||
hint_stmt=None,
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue