This commit is contained in:
ton
2024-10-07 10:13:40 +07:00
parent aa1631742f
commit 3a7d696db6
9729 changed files with 1832837 additions and 161742 deletions

View File

@@ -1,34 +1,25 @@
from dataclasses import dataclass
from pip._vendor.packaging.version import Version
from pip._vendor.packaging.version import parse as parse_version
from pip._internal.models.link import Link
from pip._internal.utils.models import KeyBasedCompareMixin
class InstallationCandidate(KeyBasedCompareMixin):
@dataclass(frozen=True)
class InstallationCandidate:
"""Represents a potential "candidate" for installation."""
__slots__ = ["name", "version", "link"]
name: str
version: Version
link: Link
def __init__(self, name: str, version: str, link: Link) -> None:
self.name = name
self.version = parse_version(version)
self.link = link
super().__init__(
key=(self.name, self.version, self.link),
defining_class=InstallationCandidate,
)
def __repr__(self) -> str:
return "<InstallationCandidate({!r}, {!r}, {!r})>".format(
self.name,
self.version,
self.link,
)
object.__setattr__(self, "name", name)
object.__setattr__(self, "version", parse_version(version))
object.__setattr__(self, "link", link)
def __str__(self) -> str:
return "{!r} candidate (version {} at {})".format(
self.name,
self.version,
self.link,
)
return f"{self.name!r} candidate (version {self.version} at {self.link})"

View File

@@ -1,8 +1,10 @@
""" PEP 610 """
import json
import re
import urllib.parse
from typing import Any, Dict, Iterable, Optional, Type, TypeVar, Union
from dataclasses import dataclass
from typing import Any, ClassVar, Dict, Iterable, Optional, Type, TypeVar, Union
__all__ = [
"DirectUrl",
@@ -31,9 +33,7 @@ def _get(
value = d[key]
if not isinstance(value, expected_type):
raise DirectUrlValidationError(
"{!r} has unexpected type for {} (expected {})".format(
value, key, expected_type
)
f"{value!r} has unexpected type for {key} (expected {expected_type})"
)
return value
@@ -66,18 +66,13 @@ def _filter_none(**kwargs: Any) -> Dict[str, Any]:
return {k: v for k, v in kwargs.items() if v is not None}
@dataclass
class VcsInfo:
name = "vcs_info"
name: ClassVar = "vcs_info"
def __init__(
self,
vcs: str,
commit_id: str,
requested_revision: Optional[str] = None,
) -> None:
self.vcs = vcs
self.requested_revision = requested_revision
self.commit_id = commit_id
vcs: str
commit_id: str
requested_revision: Optional[str] = None
@classmethod
def _from_dict(cls, d: Optional[Dict[str, Any]]) -> Optional["VcsInfo"]:
@@ -141,14 +136,11 @@ class ArchiveInfo:
return _filter_none(hash=self.hash, hashes=self.hashes)
@dataclass
class DirInfo:
name = "dir_info"
name: ClassVar = "dir_info"
def __init__(
self,
editable: bool = False,
) -> None:
self.editable = editable
editable: bool = False
@classmethod
def _from_dict(cls, d: Optional[Dict[str, Any]]) -> Optional["DirInfo"]:
@@ -163,16 +155,11 @@ class DirInfo:
InfoType = Union[ArchiveInfo, DirInfo, VcsInfo]
@dataclass
class DirectUrl:
def __init__(
self,
url: str,
info: InfoType,
subdirectory: Optional[str] = None,
) -> None:
self.url = url
self.info = info
self.subdirectory = subdirectory
url: str
info: InfoType
subdirectory: Optional[str] = None
def _remove_auth_from_netloc(self, netloc: str) -> str:
if "@" not in netloc:

View File

@@ -33,9 +33,7 @@ class FormatControl:
return all(getattr(self, k) == getattr(other, k) for k in self.__slots__)
def __repr__(self) -> str:
return "{}({}, {})".format(
self.__class__.__name__, self.no_binary, self.only_binary
)
return f"{self.__class__.__name__}({self.no_binary}, {self.only_binary})"
@staticmethod
def handle_mutual_excludes(value: str, target: Set[str], other: Set[str]) -> None:

View File

@@ -23,6 +23,9 @@ class InstallationReport:
# includes editable requirements), and false if the requirement was
# downloaded from a PEP 503 index or --find-links.
"is_direct": ireq.is_direct,
# is_yanked is true if the requirement was yanked from the index, but
# was still selected by pip to conform to PEP 592.
"is_yanked": ireq.link.is_yanked if ireq.link else False,
# requested is true if the requirement was specified by the user (aka
# top level requirement), and false if it was installed as a dependency of a
# requirement. https://peps.python.org/pep-0376/#requested
@@ -33,7 +36,7 @@ class InstallationReport:
}
if ireq.user_supplied and ireq.extras:
# For top level requirements, the list of requested extras, if any.
res["requested_extras"] = list(sorted(ireq.extras))
res["requested_extras"] = sorted(ireq.extras)
return res
def to_dict(self) -> Dict[str, Any]:

View File

@@ -27,7 +27,6 @@ from pip._internal.utils.misc import (
split_auth_from_netloc,
splitext,
)
from pip._internal.utils.models import KeyBasedCompareMixin
from pip._internal.utils.urls import path_to_url, url_to_path
if TYPE_CHECKING:
@@ -179,7 +178,8 @@ def _ensure_quoted_url(url: str) -> str:
return urllib.parse.urlunparse(result._replace(path=path))
class Link(KeyBasedCompareMixin):
@functools.total_ordering
class Link:
"""Represents a parsed link from a Package Index's simple URL"""
__slots__ = [
@@ -254,8 +254,6 @@ class Link(KeyBasedCompareMixin):
self.yanked_reason = yanked_reason
self.metadata_file_data = metadata_file_data
super().__init__(key=url, defining_class=Link)
self.cache_link_parsing = cache_link_parsing
self.egg_fragment = self._egg_fragment()
@@ -368,15 +366,26 @@ class Link(KeyBasedCompareMixin):
else:
rp = ""
if self.comes_from:
return "{} (from {}){}".format(
redact_auth_from_url(self._url), self.comes_from, rp
)
return f"{redact_auth_from_url(self._url)} (from {self.comes_from}){rp}"
else:
return redact_auth_from_url(str(self._url))
def __repr__(self) -> str:
return f"<Link {self}>"
def __hash__(self) -> int:
return hash(self.url)
def __eq__(self, other: Any) -> bool:
if not isinstance(other, Link):
return NotImplemented
return self.url == other.url
def __lt__(self, other: Any) -> bool:
if not isinstance(other, Link):
return NotImplemented
return self.url < other.url
@property
def url(self) -> str:
return self._url

View File

@@ -5,10 +5,12 @@ For a general overview of available schemes and their context, see
https://docs.python.org/3/install/index.html#alternate-installation.
"""
from dataclasses import dataclass
SCHEME_KEYS = ["platlib", "purelib", "headers", "scripts", "data"]
@dataclass(frozen=True)
class Scheme:
"""A Scheme holds paths which are used as the base directories for
artifacts associated with a Python package.
@@ -16,16 +18,8 @@ class Scheme:
__slots__ = SCHEME_KEYS
def __init__(
self,
platlib: str,
purelib: str,
headers: str,
scripts: str,
data: str,
) -> None:
self.platlib = platlib
self.purelib = purelib
self.headers = headers
self.scripts = scripts
self.data = data
platlib: str
purelib: str
headers: str
scripts: str
data: str

View File

@@ -3,6 +3,7 @@ import logging
import os
import posixpath
import urllib.parse
from dataclasses import dataclass
from typing import List
from pip._vendor.packaging.utils import canonicalize_name
@@ -14,14 +15,18 @@ from pip._internal.utils.misc import normalize_path, redact_auth_from_url
logger = logging.getLogger(__name__)
@dataclass(frozen=True)
class SearchScope:
"""
Encapsulates the locations that pip is configured to search.
"""
__slots__ = ["find_links", "index_urls", "no_index"]
find_links: List[str]
index_urls: List[str]
no_index: bool
@classmethod
def create(
cls,
@@ -64,16 +69,6 @@ class SearchScope:
no_index=no_index,
)
def __init__(
self,
find_links: List[str],
index_urls: List[str],
no_index: bool,
) -> None:
self.find_links = find_links
self.index_urls = index_urls
self.no_index = no_index
def get_formatted_locations(self) -> str:
lines = []
redacted_index_urls = []

View File

@@ -3,6 +3,8 @@ from typing import Optional
from pip._internal.models.format_control import FormatControl
# TODO: This needs Python 3.10's improved slots support for dataclasses
# to be converted into a dataclass.
class SelectionPreferences:
"""
Encapsulates the candidate selection preferences for downloading

View File

@@ -1,5 +1,5 @@
import sys
from typing import List, Optional, Tuple
from typing import List, Optional, Set, Tuple
from pip._vendor.packaging.tags import Tag
@@ -8,7 +8,6 @@ from pip._internal.utils.misc import normalize_version_info
class TargetPython:
"""
Encapsulates the properties of a Python interpreter one is targeting
for a package install, download, etc.
@@ -22,6 +21,7 @@ class TargetPython:
"py_version",
"py_version_info",
"_valid_tags",
"_valid_tags_set",
]
def __init__(
@@ -61,8 +61,9 @@ class TargetPython:
self.py_version = py_version
self.py_version_info = py_version_info
# This is used to cache the return value of get_tags().
# This is used to cache the return value of get_(un)sorted_tags.
self._valid_tags: Optional[List[Tag]] = None
self._valid_tags_set: Optional[Set[Tag]] = None
def format_given(self) -> str:
"""
@@ -84,7 +85,7 @@ class TargetPython:
f"{key}={value!r}" for key, value in key_values if value is not None
)
def get_tags(self) -> List[Tag]:
def get_sorted_tags(self) -> List[Tag]:
"""
Return the supported PEP 425 tags to check wheel candidates against.
@@ -108,3 +109,13 @@ class TargetPython:
self._valid_tags = tags
return self._valid_tags
def get_unsorted_tags(self) -> Set[Tag]:
"""Exactly the same as get_sorted_tags, but returns a set.
This is important for performance.
"""
if self._valid_tags_set is None:
self._valid_tags_set = set(self.get_sorted_tags())
return self._valid_tags_set

View File

@@ -1,6 +1,7 @@
"""Represents a wheel file and provides access to the various parts of the
name that have meaning.
"""
import re
from typing import Dict, Iterable, List