From 9468226a9e2e2ab8cdd599f1d8538e860ca86120 Mon Sep 17 00:00:00 2001 From: Biswakalyan Bhuyan Date: Sun, 13 Nov 2022 23:46:45 +0530 Subject: id card generator --- .../site-packages/pip/_internal/models/__init__.py | 2 + .../models/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 245 bytes .../models/__pycache__/candidate.cpython-310.pyc | Bin 0 -> 1397 bytes .../models/__pycache__/direct_url.cpython-310.pyc | Bin 0 -> 7087 bytes .../__pycache__/format_control.cpython-310.pyc | Bin 0 -> 2722 bytes .../models/__pycache__/index.cpython-310.pyc | Bin 0 -> 1214 bytes .../installation_report.cpython-310.pyc | Bin 0 -> 1724 bytes .../models/__pycache__/link.cpython-310.pyc | Bin 0 -> 10520 bytes .../models/__pycache__/scheme.cpython-310.pyc | Bin 0 -> 1013 bytes .../__pycache__/search_scope.cpython-310.pyc | Bin 0 -> 3468 bytes .../__pycache__/selection_prefs.cpython-310.pyc | Bin 0 -> 1675 bytes .../__pycache__/target_python.cpython-310.pyc | Bin 0 -> 3426 bytes .../models/__pycache__/wheel.cpython-310.pyc | Bin 0 -> 4420 bytes .../pip/_internal/models/candidate.py | 34 +++ .../pip/_internal/models/direct_url.py | 212 ++++++++++++++ .../pip/_internal/models/format_control.py | 80 ++++++ .../site-packages/pip/_internal/models/index.py | 28 ++ .../pip/_internal/models/installation_report.py | 53 ++++ .../site-packages/pip/_internal/models/link.py | 314 +++++++++++++++++++++ .../site-packages/pip/_internal/models/scheme.py | 31 ++ .../pip/_internal/models/search_scope.py | 129 +++++++++ .../pip/_internal/models/selection_prefs.py | 51 ++++ .../pip/_internal/models/target_python.py | 110 ++++++++ .../site-packages/pip/_internal/models/wheel.py | 92 ++++++ 24 files changed, 1136 insertions(+) create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/__init__.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/__init__.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/candidate.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/direct_url.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/format_control.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/index.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/installation_report.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/link.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/scheme.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/search_scope.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/selection_prefs.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/target_python.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/wheel.cpython-310.pyc create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/candidate.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/direct_url.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/format_control.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/index.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/installation_report.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/link.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/scheme.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/search_scope.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/selection_prefs.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/target_python.py create mode 100644 env/lib/python3.10/site-packages/pip/_internal/models/wheel.py (limited to 'env/lib/python3.10/site-packages/pip/_internal/models') diff --git a/env/lib/python3.10/site-packages/pip/_internal/models/__init__.py b/env/lib/python3.10/site-packages/pip/_internal/models/__init__.py new file mode 100644 index 0000000..7855226 --- /dev/null +++ b/env/lib/python3.10/site-packages/pip/_internal/models/__init__.py @@ -0,0 +1,2 @@ +"""A package that contains models that represent entities. +""" diff --git a/env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/__init__.cpython-310.pyc b/env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000..cae0ca3 Binary files /dev/null and b/env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/__init__.cpython-310.pyc differ diff --git a/env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/candidate.cpython-310.pyc b/env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/candidate.cpython-310.pyc new file mode 100644 index 0000000..e6cd9ba Binary files /dev/null and b/env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/candidate.cpython-310.pyc differ diff --git a/env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/direct_url.cpython-310.pyc b/env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/direct_url.cpython-310.pyc new file mode 100644 index 0000000..812bb2f Binary files /dev/null and b/env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/direct_url.cpython-310.pyc differ diff --git a/env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/format_control.cpython-310.pyc b/env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/format_control.cpython-310.pyc new file mode 100644 index 0000000..656dff8 Binary files /dev/null and b/env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/format_control.cpython-310.pyc differ diff --git a/env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/index.cpython-310.pyc b/env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/index.cpython-310.pyc new file mode 100644 index 0000000..98286df Binary files /dev/null and b/env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/index.cpython-310.pyc differ diff --git a/env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/installation_report.cpython-310.pyc b/env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/installation_report.cpython-310.pyc new file mode 100644 index 0000000..cf15936 Binary files /dev/null and b/env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/installation_report.cpython-310.pyc differ diff --git a/env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/link.cpython-310.pyc b/env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/link.cpython-310.pyc new file mode 100644 index 0000000..0b6d8be Binary files /dev/null and b/env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/link.cpython-310.pyc differ diff --git a/env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/scheme.cpython-310.pyc b/env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/scheme.cpython-310.pyc new file mode 100644 index 0000000..4bdb064 Binary files /dev/null and b/env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/scheme.cpython-310.pyc differ diff --git a/env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/search_scope.cpython-310.pyc b/env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/search_scope.cpython-310.pyc new file mode 100644 index 0000000..9aa9fe7 Binary files /dev/null and b/env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/search_scope.cpython-310.pyc differ diff --git a/env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/selection_prefs.cpython-310.pyc b/env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/selection_prefs.cpython-310.pyc new file mode 100644 index 0000000..defb6b7 Binary files /dev/null and b/env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/selection_prefs.cpython-310.pyc differ diff --git a/env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/target_python.cpython-310.pyc b/env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/target_python.cpython-310.pyc new file mode 100644 index 0000000..e4104f8 Binary files /dev/null and b/env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/target_python.cpython-310.pyc differ diff --git a/env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/wheel.cpython-310.pyc b/env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/wheel.cpython-310.pyc new file mode 100644 index 0000000..7187659 Binary files /dev/null and b/env/lib/python3.10/site-packages/pip/_internal/models/__pycache__/wheel.cpython-310.pyc differ diff --git a/env/lib/python3.10/site-packages/pip/_internal/models/candidate.py b/env/lib/python3.10/site-packages/pip/_internal/models/candidate.py new file mode 100644 index 0000000..a4963ae --- /dev/null +++ b/env/lib/python3.10/site-packages/pip/_internal/models/candidate.py @@ -0,0 +1,34 @@ +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): + """Represents a potential "candidate" for installation.""" + + __slots__ = ["name", "version", "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 "".format( + self.name, + self.version, + self.link, + ) + + def __str__(self) -> str: + return "{!r} candidate (version {} at {})".format( + self.name, + self.version, + self.link, + ) diff --git a/env/lib/python3.10/site-packages/pip/_internal/models/direct_url.py b/env/lib/python3.10/site-packages/pip/_internal/models/direct_url.py new file mode 100644 index 0000000..e75feda --- /dev/null +++ b/env/lib/python3.10/site-packages/pip/_internal/models/direct_url.py @@ -0,0 +1,212 @@ +""" PEP 610 """ +import json +import re +import urllib.parse +from typing import Any, Dict, Iterable, Optional, Type, TypeVar, Union + +__all__ = [ + "DirectUrl", + "DirectUrlValidationError", + "DirInfo", + "ArchiveInfo", + "VcsInfo", +] + +T = TypeVar("T") + +DIRECT_URL_METADATA_NAME = "direct_url.json" +ENV_VAR_RE = re.compile(r"^\$\{[A-Za-z0-9-_]+\}(:\$\{[A-Za-z0-9-_]+\})?$") + + +class DirectUrlValidationError(Exception): + pass + + +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 + value = d[key] + if not isinstance(value, expected_type): + raise DirectUrlValidationError( + "{!r} has unexpected type for {} (expected {})".format( + value, key, expected_type + ) + ) + return value + + +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: Iterable[Optional["InfoType"]]) -> "InfoType": + infos = [info for info in infos if info is not None] + if not infos: + raise DirectUrlValidationError( + "missing one of archive_info, dir_info, vcs_info" + ) + if len(infos) > 1: + raise DirectUrlValidationError( + "more than one of archive_info, dir_info, vcs_info" + ) + assert infos[0] is not None + return infos[0] + + +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} + + +class VcsInfo: + name = "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 + + @classmethod + def _from_dict(cls, d: Optional[Dict[str, Any]]) -> Optional["VcsInfo"]: + if d is None: + return None + return cls( + vcs=_get_required(d, str, "vcs"), + commit_id=_get_required(d, str, "commit_id"), + requested_revision=_get(d, str, "requested_revision"), + ) + + def _to_dict(self) -> Dict[str, Any]: + return _filter_none( + vcs=self.vcs, + requested_revision=self.requested_revision, + commit_id=self.commit_id, + ) + + +class ArchiveInfo: + name = "archive_info" + + def __init__( + self, + hash: Optional[str] = None, + ) -> None: + self.hash = hash + + @classmethod + 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) -> Dict[str, Any]: + return _filter_none(hash=self.hash) + + +class DirInfo: + name = "dir_info" + + def __init__( + self, + editable: bool = False, + ) -> None: + self.editable = editable + + @classmethod + 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) -> Dict[str, Any]: + return _filter_none(editable=self.editable or None) + + +InfoType = Union[ArchiveInfo, DirInfo, VcsInfo] + + +class DirectUrl: + def __init__( + self, + 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: str) -> str: + if "@" not in netloc: + return netloc + user_pass, netloc_no_user_pass = netloc.split("@", 1) + if ( + isinstance(self.info, VcsInfo) + and self.info.vcs == "git" + and user_pass == "git" + ): + return netloc + if ENV_VAR_RE.match(user_pass): + return netloc + return netloc_no_user_pass + + @property + 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. + """ + purl = urllib.parse.urlsplit(self.url) + netloc = self._remove_auth_from_netloc(purl.netloc) + surl = urllib.parse.urlunsplit( + (purl.scheme, netloc, purl.path, purl.query, purl.fragment) + ) + return surl + + def validate(self) -> None: + self.from_dict(self.to_dict()) + + @classmethod + def from_dict(cls, d: Dict[str, Any]) -> "DirectUrl": + return DirectUrl( + url=_get_required(d, str, "url"), + subdirectory=_get(d, str, "subdirectory"), + info=_exactly_one_of( + [ + ArchiveInfo._from_dict(_get(d, dict, "archive_info")), + DirInfo._from_dict(_get(d, dict, "dir_info")), + VcsInfo._from_dict(_get(d, dict, "vcs_info")), + ] + ), + ) + + def to_dict(self) -> Dict[str, Any]: + res = _filter_none( + url=self.redacted_url, + subdirectory=self.subdirectory, + ) + res[self.info.name] = self.info._to_dict() + return res + + @classmethod + def from_json(cls, s: str) -> "DirectUrl": + return cls.from_dict(json.loads(s)) + + def to_json(self) -> str: + return json.dumps(self.to_dict(), sort_keys=True) + + def is_local_editable(self) -> bool: + return isinstance(self.info, DirInfo) and self.info.editable diff --git a/env/lib/python3.10/site-packages/pip/_internal/models/format_control.py b/env/lib/python3.10/site-packages/pip/_internal/models/format_control.py new file mode 100644 index 0000000..db3995e --- /dev/null +++ b/env/lib/python3.10/site-packages/pip/_internal/models/format_control.py @@ -0,0 +1,80 @@ +from typing import FrozenSet, Optional, Set + +from pip._vendor.packaging.utils import canonicalize_name + +from pip._internal.exceptions import CommandError + + +class FormatControl: + """Helper for managing formats from which a package can be installed.""" + + __slots__ = ["no_binary", "only_binary"] + + 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: + only_binary = set() + + self.no_binary = no_binary + self.only_binary = only_binary + + def __eq__(self, other: object) -> bool: + if not isinstance(other, self.__class__): + return NotImplemented + + if self.__slots__ != other.__slots__: + return False + + 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 + ) + + @staticmethod + 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." + ) + new = value.split(",") + while ":all:" in new: + other.clear() + target.clear() + target.add(":all:") + del new[: new.index(":all:") + 1] + # Without a none, we want to discard everything as :all: covers it + if ":none:" not in new: + return + for name in new: + if name == ":none:": + target.clear() + continue + name = canonicalize_name(name) + other.discard(name) + target.add(name) + + def get_allowed_formats(self, canonical_name: str) -> FrozenSet[str]: + result = {"binary", "source"} + if canonical_name in self.only_binary: + result.discard("source") + elif canonical_name in self.no_binary: + result.discard("binary") + elif ":all:" in self.only_binary: + result.discard("source") + elif ":all:" in self.no_binary: + result.discard("binary") + return frozenset(result) + + def disallow_binaries(self) -> None: + self.handle_mutual_excludes( + ":all:", + self.no_binary, + self.only_binary, + ) diff --git a/env/lib/python3.10/site-packages/pip/_internal/models/index.py b/env/lib/python3.10/site-packages/pip/_internal/models/index.py new file mode 100644 index 0000000..b94c325 --- /dev/null +++ b/env/lib/python3.10/site-packages/pip/_internal/models/index.py @@ -0,0 +1,28 @@ +import urllib.parse + + +class PackageIndex: + """Represents a Package Index and provides easier access to endpoints""" + + __slots__ = ["url", "netloc", "simple_url", "pypi_url", "file_storage_domain"] + + def __init__(self, url: str, file_storage_domain: str) -> None: + super().__init__() + self.url = url + self.netloc = urllib.parse.urlsplit(url).netloc + self.simple_url = self._url_for_path("simple") + self.pypi_url = self._url_for_path("pypi") + + # This is part of a temporary hack used to block installs of PyPI + # packages which depend on external urls only necessary until PyPI can + # block such packages themselves + self.file_storage_domain = file_storage_domain + + def _url_for_path(self, path: str) -> str: + return urllib.parse.urljoin(self.url, path) + + +PyPI = PackageIndex("https://pypi.org/", file_storage_domain="files.pythonhosted.org") +TestPyPI = PackageIndex( + "https://test.pypi.org/", file_storage_domain="test-files.pythonhosted.org" +) diff --git a/env/lib/python3.10/site-packages/pip/_internal/models/installation_report.py b/env/lib/python3.10/site-packages/pip/_internal/models/installation_report.py new file mode 100644 index 0000000..965f095 --- /dev/null +++ b/env/lib/python3.10/site-packages/pip/_internal/models/installation_report.py @@ -0,0 +1,53 @@ +from typing import Any, Dict, Sequence + +from pip._vendor.packaging.markers import default_environment + +from pip import __version__ +from pip._internal.req.req_install import InstallRequirement + + +class InstallationReport: + def __init__(self, install_requirements: Sequence[InstallRequirement]): + self._install_requirements = install_requirements + + @classmethod + def _install_req_to_dict(cls, ireq: InstallRequirement) -> Dict[str, Any]: + assert ireq.download_info, f"No download_info for {ireq}" + res = { + # PEP 610 json for the download URL. download_info.archive_info.hash may + # be absent when the requirement was installed from the wheel cache + # and the cache entry was populated by an older pip version that did not + # record origin.json. + "download_info": ireq.download_info.to_dict(), + # is_direct is true if the requirement was a direct URL reference (which + # includes editable requirements), and false if the requirement was + # downloaded from a PEP 503 index or --find-links. + "is_direct": bool(ireq.original_link), + # 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 + "requested": ireq.user_supplied, + # PEP 566 json encoding for metadata + # https://www.python.org/dev/peps/pep-0566/#json-compatible-metadata + "metadata": ireq.get_dist().metadata_dict, + } + 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)) + return res + + def to_dict(self) -> Dict[str, Any]: + return { + "version": "0", + "pip_version": __version__, + "install": [ + self._install_req_to_dict(ireq) for ireq in self._install_requirements + ], + # https://peps.python.org/pep-0508/#environment-markers + # TODO: currently, the resolver uses the default environment to evaluate + # environment markers, so that is what we report here. In the future, it + # should also take into account options such as --python-version or + # --platform, perhaps under the form of an environment_override field? + # https://github.com/pypa/pip/issues/11198 + "environment": default_environment(), + } diff --git a/env/lib/python3.10/site-packages/pip/_internal/models/link.py b/env/lib/python3.10/site-packages/pip/_internal/models/link.py new file mode 100644 index 0000000..8fd1c3d --- /dev/null +++ b/env/lib/python3.10/site-packages/pip/_internal/models/link.py @@ -0,0 +1,314 @@ +import functools +import logging +import os +import posixpath +import re +import urllib.parse +from typing import ( + TYPE_CHECKING, + Dict, + List, + Mapping, + NamedTuple, + Optional, + Tuple, + Union, +) + +from pip._internal.utils.filetypes import WHEEL_EXTENSION +from pip._internal.utils.hashes import Hashes +from pip._internal.utils.misc import ( + redact_auth_from_url, + 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: + from pip._internal.index.collector import IndexContent + +logger = logging.getLogger(__name__) + + +# Order matters, earlier hashes have a precedence over later hashes for what +# we will pick to use. +_SUPPORTED_HASHES = ("sha512", "sha384", "sha256", "sha224", "sha1", "md5") + + +class Link(KeyBasedCompareMixin): + """Represents a parsed link from a Package Index's simple URL""" + + __slots__ = [ + "_parsed_url", + "_url", + "_hashes", + "comes_from", + "requires_python", + "yanked_reason", + "cache_link_parsing", + ] + + def __init__( + self, + url: str, + comes_from: Optional[Union[str, "IndexContent"]] = None, + requires_python: Optional[str] = None, + yanked_reason: Optional[str] = None, + cache_link_parsing: bool = True, + hashes: Optional[Mapping[str, str]] = None, + ) -> None: + """ + :param url: url of the resource pointed to (href of the link) + :param comes_from: instance of IndexContent where the link was found, + or string. + :param requires_python: String containing the `Requires-Python` + metadata field, specified in PEP 345. This may be specified by + a data-requires-python attribute in the HTML link tag, as + described in PEP 503. + :param yanked_reason: the reason the file has been yanked, if the + file has been yanked, or None if the file hasn't been yanked. + This is the value of the "data-yanked" attribute, if present, in + a simple repository HTML link. If the file has been yanked but + no reason was provided, this should be the empty string. See + PEP 592 for more information and the specification. + :param cache_link_parsing: A flag that is used elsewhere to determine + whether resources retrieved from this link + should be cached. PyPI index urls should + generally have this set to False, for + example. + :param hashes: A mapping of hash names to digests to allow us to + determine the validity of a download. + """ + + # url can be a UNC windows share + if url.startswith("\\\\"): + url = path_to_url(url) + + self._parsed_url = urllib.parse.urlsplit(url) + # Store the url as a private attribute to prevent accidentally + # trying to set a new value. + self._url = url + self._hashes = hashes if hashes is not None else {} + + self.comes_from = comes_from + self.requires_python = requires_python if requires_python else None + self.yanked_reason = yanked_reason + + super().__init__(key=url, defining_class=Link) + + self.cache_link_parsing = cache_link_parsing + + def __str__(self) -> str: + if self.requires_python: + rp = f" (requires-python:{self.requires_python})" + else: + rp = "" + if self.comes_from: + return "{} (from {}){}".format( + redact_auth_from_url(self._url), self.comes_from, rp + ) + else: + return redact_auth_from_url(str(self._url)) + + def __repr__(self) -> str: + return f"" + + @property + def url(self) -> str: + return self._url + + @property + def filename(self) -> str: + path = self.path.rstrip("/") + name = posixpath.basename(path) + if not name: + # Make sure we don't leak auth information if the netloc + # includes a username and password. + netloc, user_pass = split_auth_from_netloc(self.netloc) + return netloc + + name = urllib.parse.unquote(name) + assert name, f"URL {self._url!r} produced no filename" + return name + + @property + def file_path(self) -> str: + return url_to_path(self.url) + + @property + def scheme(self) -> str: + return self._parsed_url.scheme + + @property + def netloc(self) -> str: + """ + This can contain auth information. + """ + return self._parsed_url.netloc + + @property + def path(self) -> str: + return urllib.parse.unquote(self._parsed_url.path) + + def splitext(self) -> Tuple[str, str]: + return splitext(posixpath.basename(self.path.rstrip("/"))) + + @property + def ext(self) -> str: + return self.splitext()[1] + + @property + def url_without_fragment(self) -> str: + scheme, netloc, path, query, fragment = self._parsed_url + return urllib.parse.urlunsplit((scheme, netloc, path, query, "")) + + _egg_fragment_re = re.compile(r"[#&]egg=([^&]*)") + + @property + def egg_fragment(self) -> Optional[str]: + match = self._egg_fragment_re.search(self._url) + if not match: + return None + return match.group(1) + + _subdirectory_fragment_re = re.compile(r"[#&]subdirectory=([^&]*)") + + @property + def subdirectory_fragment(self) -> Optional[str]: + match = self._subdirectory_fragment_re.search(self._url) + if not match: + return None + return match.group(1) + + _hash_re = re.compile( + r"({choices})=([a-f0-9]+)".format(choices="|".join(_SUPPORTED_HASHES)) + ) + + @property + def hash(self) -> Optional[str]: + for hashname in _SUPPORTED_HASHES: + if hashname in self._hashes: + return self._hashes[hashname] + + match = self._hash_re.search(self._url) + if match: + return match.group(2) + + return None + + @property + def hash_name(self) -> Optional[str]: + for hashname in _SUPPORTED_HASHES: + if hashname in self._hashes: + return hashname + + match = self._hash_re.search(self._url) + if match: + return match.group(1) + + return None + + @property + def show_url(self) -> str: + return posixpath.basename(self._url.split("#", 1)[0].split("?", 1)[0]) + + @property + def is_file(self) -> bool: + return self.scheme == "file" + + def is_existing_dir(self) -> bool: + return self.is_file and os.path.isdir(self.file_path) + + @property + def is_wheel(self) -> bool: + return self.ext == WHEEL_EXTENSION + + @property + def is_vcs(self) -> bool: + from pip._internal.vcs import vcs + + return self.scheme in vcs.all_schemes + + @property + def is_yanked(self) -> bool: + return self.yanked_reason is not None + + @property + def has_hash(self) -> bool: + return self.hash_name is not None + + def is_hash_allowed(self, hashes: Optional[Hashes]) -> bool: + """ + Return True if the link has a hash and it is allowed. + """ + if hashes is None or not self.has_hash: + return False + # Assert non-None so mypy knows self.hash_name and self.hash are str. + assert self.hash_name is not None + assert self.hash is not None + + return hashes.is_hash_allowed(self.hash_name, hex_digest=self.hash) + + +class _CleanResult(NamedTuple): + """Convert link for equivalency check. + + This is used in the resolver to check whether two URL-specified requirements + likely point to the same distribution and can be considered equivalent. This + equivalency logic avoids comparing URLs literally, which can be too strict + (e.g. "a=1&b=2" vs "b=2&a=1") and produce conflicts unexpecting to users. + + Currently this does three things: + + 1. Drop the basic auth part. This is technically wrong since a server can + serve different content based on auth, but if it does that, it is even + impossible to guarantee two URLs without auth are equivalent, since + the user can input different auth information when prompted. So the + practical solution is to assume the auth doesn't affect the response. + 2. Parse the query to avoid the ordering issue. Note that ordering under the + same key in the query are NOT cleaned; i.e. "a=1&a=2" and "a=2&a=1" are + still considered different. + 3. Explicitly drop most of the fragment part, except ``subdirectory=`` and + hash values, since it should have no impact the downloaded content. Note + that this drops the "egg=" part historically used to denote the requested + project (and extras), which is wrong in the strictest sense, but too many + people are supplying it inconsistently to cause superfluous resolution + conflicts, so we choose to also ignore them. + """ + + parsed: urllib.parse.SplitResult + query: Dict[str, List[str]] + subdirectory: str + hashes: Dict[str, str] + + +def _clean_link(link: Link) -> _CleanResult: + parsed = link._parsed_url + netloc = parsed.netloc.rsplit("@", 1)[-1] + # According to RFC 8089, an empty host in file: means localhost. + if parsed.scheme == "file" and not netloc: + netloc = "localhost" + fragment = urllib.parse.parse_qs(parsed.fragment) + if "egg" in fragment: + logger.debug("Ignoring egg= fragment in %s", link) + try: + # If there are multiple subdirectory values, use the first one. + # This matches the behavior of Link.subdirectory_fragment. + subdirectory = fragment["subdirectory"][0] + except (IndexError, KeyError): + subdirectory = "" + # If there are multiple hash values under the same algorithm, use the + # first one. This matches the behavior of Link.hash_value. + hashes = {k: fragment[k][0] for k in _SUPPORTED_HASHES if k in fragment} + return _CleanResult( + parsed=parsed._replace(netloc=netloc, query="", fragment=""), + query=urllib.parse.parse_qs(parsed.query), + subdirectory=subdirectory, + hashes=hashes, + ) + + +@functools.lru_cache(maxsize=None) +def links_equivalent(link1: Link, link2: Link) -> bool: + return _clean_link(link1) == _clean_link(link2) diff --git a/env/lib/python3.10/site-packages/pip/_internal/models/scheme.py b/env/lib/python3.10/site-packages/pip/_internal/models/scheme.py new file mode 100644 index 0000000..f51190a --- /dev/null +++ b/env/lib/python3.10/site-packages/pip/_internal/models/scheme.py @@ -0,0 +1,31 @@ +""" +For types associated with installation schemes. + +For a general overview of available schemes and their context, see +https://docs.python.org/3/install/index.html#alternate-installation. +""" + + +SCHEME_KEYS = ["platlib", "purelib", "headers", "scripts", "data"] + + +class Scheme: + """A Scheme holds paths which are used as the base directories for + artifacts associated with a Python package. + """ + + __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 diff --git a/env/lib/python3.10/site-packages/pip/_internal/models/search_scope.py b/env/lib/python3.10/site-packages/pip/_internal/models/search_scope.py new file mode 100644 index 0000000..e4e54c2 --- /dev/null +++ b/env/lib/python3.10/site-packages/pip/_internal/models/search_scope.py @@ -0,0 +1,129 @@ +import itertools +import logging +import os +import posixpath +import urllib.parse +from typing import List + +from pip._vendor.packaging.utils import canonicalize_name + +from pip._internal.models.index import PyPI +from pip._internal.utils.compat import has_tls +from pip._internal.utils.misc import normalize_path, redact_auth_from_url + +logger = logging.getLogger(__name__) + + +class SearchScope: + + """ + Encapsulates the locations that pip is configured to search. + """ + + __slots__ = ["find_links", "index_urls"] + + @classmethod + def create( + cls, + find_links: List[str], + index_urls: List[str], + ) -> "SearchScope": + """ + Create a SearchScope object after normalizing the `find_links`. + """ + # Build find_links. If an argument starts with ~, it may be + # a local file relative to a home directory. So try normalizing + # it and if it exists, use the normalized version. + # This is deliberately conservative - it might be fine just to + # blindly normalize anything starting with a ~... + built_find_links: List[str] = [] + for link in find_links: + if link.startswith("~"): + new_link = normalize_path(link) + if os.path.exists(new_link): + link = new_link + built_find_links.append(link) + + # If we don't have TLS enabled, then WARN if anyplace we're looking + # relies on TLS. + if not has_tls(): + for link in itertools.chain(index_urls, built_find_links): + parsed = urllib.parse.urlparse(link) + if parsed.scheme == "https": + logger.warning( + "pip is configured with locations that require " + "TLS/SSL, however the ssl module in Python is not " + "available." + ) + break + + return cls( + find_links=built_find_links, + index_urls=index_urls, + ) + + def __init__( + self, + find_links: List[str], + index_urls: List[str], + ) -> None: + self.find_links = find_links + self.index_urls = index_urls + + def get_formatted_locations(self) -> str: + lines = [] + redacted_index_urls = [] + if self.index_urls and self.index_urls != [PyPI.simple_url]: + for url in self.index_urls: + + redacted_index_url = redact_auth_from_url(url) + + # Parse the URL + purl = urllib.parse.urlsplit(redacted_index_url) + + # URL is generally invalid if scheme and netloc is missing + # there are issues with Python and URL parsing, so this test + # is a bit crude. See bpo-20271, bpo-23505. Python doesn't + # always parse invalid URLs correctly - it should raise + # exceptions for malformed URLs + if not purl.scheme and not purl.netloc: + logger.warning( + 'The index url "%s" seems invalid, please provide a scheme.', + redacted_index_url, + ) + + redacted_index_urls.append(redacted_index_url) + + lines.append( + "Looking in indexes: {}".format(", ".join(redacted_index_urls)) + ) + + if self.find_links: + lines.append( + "Looking in links: {}".format( + ", ".join(redact_auth_from_url(url) for url in self.find_links) + ) + ) + return "\n".join(lines) + + def get_index_urls_locations(self, project_name: str) -> List[str]: + """Returns the locations found via self.index_urls + + Checks the url_name on the main (first in the list) index and + use this url_name to produce all locations + """ + + def mkurl_pypi_url(url: str) -> str: + loc = posixpath.join( + url, urllib.parse.quote(canonicalize_name(project_name)) + ) + # For maximum compatibility with easy_install, ensure the path + # ends in a trailing slash. Although this isn't in the spec + # (and PyPI can handle it without the slash) some other index + # implementations might break if they relied on easy_install's + # behavior. + if not loc.endswith("/"): + loc = loc + "/" + return loc + + return [mkurl_pypi_url(url) for url in self.index_urls] diff --git a/env/lib/python3.10/site-packages/pip/_internal/models/selection_prefs.py b/env/lib/python3.10/site-packages/pip/_internal/models/selection_prefs.py new file mode 100644 index 0000000..977bc4c --- /dev/null +++ b/env/lib/python3.10/site-packages/pip/_internal/models/selection_prefs.py @@ -0,0 +1,51 @@ +from typing import Optional + +from pip._internal.models.format_control import FormatControl + + +class SelectionPreferences: + """ + Encapsulates the candidate selection preferences for downloading + and installing files. + """ + + __slots__ = [ + "allow_yanked", + "allow_all_prereleases", + "format_control", + "prefer_binary", + "ignore_requires_python", + ] + + # Don't include an allow_yanked default value to make sure each call + # site considers whether yanked releases are allowed. This also causes + # that decision to be made explicit in the calling code, which helps + # people when reading the code. + def __init__( + self, + allow_yanked: bool, + allow_all_prereleases: bool = False, + format_control: Optional[FormatControl] = None, + prefer_binary: bool = False, + ignore_requires_python: Optional[bool] = None, + ) -> None: + """Create a SelectionPreferences object. + + :param allow_yanked: Whether files marked as yanked (in the sense + of PEP 592) are permitted to be candidates for install. + :param format_control: A FormatControl object or None. Used to control + the selection of source packages / binary packages when consulting + the index and links. + :param prefer_binary: Whether to prefer an old, but valid, binary + dist over a new source dist. + :param ignore_requires_python: Whether to ignore incompatible + "Requires-Python" values in links. Defaults to False. + """ + if ignore_requires_python is None: + ignore_requires_python = False + + self.allow_yanked = allow_yanked + self.allow_all_prereleases = allow_all_prereleases + self.format_control = format_control + self.prefer_binary = prefer_binary + self.ignore_requires_python = ignore_requires_python diff --git a/env/lib/python3.10/site-packages/pip/_internal/models/target_python.py b/env/lib/python3.10/site-packages/pip/_internal/models/target_python.py new file mode 100644 index 0000000..744bd7e --- /dev/null +++ b/env/lib/python3.10/site-packages/pip/_internal/models/target_python.py @@ -0,0 +1,110 @@ +import sys +from typing import List, Optional, Tuple + +from pip._vendor.packaging.tags import Tag + +from pip._internal.utils.compatibility_tags import get_supported, version_info_to_nodot +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. + """ + + __slots__ = [ + "_given_py_version_info", + "abis", + "implementation", + "platforms", + "py_version", + "py_version_info", + "_valid_tags", + ] + + def __init__( + self, + platforms: Optional[List[str]] = None, + py_version_info: Optional[Tuple[int, ...]] = None, + abis: Optional[List[str]] = None, + implementation: Optional[str] = None, + ) -> None: + """ + :param platforms: A list of strings or None. If None, searches for + packages that are supported by the current system. Otherwise, will + find packages that can be built on the platforms passed in. These + packages will only be downloaded for distribution: they will + not be built locally. + :param py_version_info: An optional tuple of ints representing the + Python version information to use (e.g. `sys.version_info[:3]`). + This can have length 1, 2, or 3 when provided. + :param abis: A list of strings or None. This is passed to + compatibility_tags.py's get_supported() function as is. + :param implementation: A string or None. This is passed to + compatibility_tags.py's get_supported() function as is. + """ + # Store the given py_version_info for when we call get_supported(). + self._given_py_version_info = py_version_info + + if py_version_info is None: + py_version_info = sys.version_info[:3] + else: + py_version_info = normalize_version_info(py_version_info) + + py_version = ".".join(map(str, py_version_info[:2])) + + self.abis = abis + self.implementation = implementation + self.platforms = platforms + self.py_version = py_version + self.py_version_info = py_version_info + + # This is used to cache the return value of get_tags(). + self._valid_tags: Optional[List[Tag]] = None + + def format_given(self) -> str: + """ + Format the given, non-None attributes for display. + """ + display_version = None + if self._given_py_version_info is not None: + display_version = ".".join( + str(part) for part in self._given_py_version_info + ) + + key_values = [ + ("platforms", self.platforms), + ("version_info", display_version), + ("abis", self.abis), + ("implementation", self.implementation), + ] + return " ".join( + f"{key}={value!r}" for key, value in key_values if value is not None + ) + + def get_tags(self) -> List[Tag]: + """ + Return the supported PEP 425 tags to check wheel candidates against. + + The tags are returned in order of preference (most preferred first). + """ + if self._valid_tags is None: + # Pass versions=None if no py_version_info was given since + # versions=None uses special default logic. + py_version_info = self._given_py_version_info + if py_version_info is None: + version = None + else: + version = version_info_to_nodot(py_version_info) + + tags = get_supported( + version=version, + platforms=self.platforms, + abis=self.abis, + impl=self.implementation, + ) + self._valid_tags = tags + + return self._valid_tags diff --git a/env/lib/python3.10/site-packages/pip/_internal/models/wheel.py b/env/lib/python3.10/site-packages/pip/_internal/models/wheel.py new file mode 100644 index 0000000..35c7037 --- /dev/null +++ b/env/lib/python3.10/site-packages/pip/_internal/models/wheel.py @@ -0,0 +1,92 @@ +"""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 + +from pip._vendor.packaging.tags import Tag + +from pip._internal.exceptions import InvalidWheelFilename + + +class Wheel: + """A wheel file""" + + wheel_file_re = re.compile( + r"""^(?P(?P.+?)-(?P.*?)) + ((-(?P\d[^-]*?))?-(?P.+?)-(?P.+?)-(?P.+?) + \.whl|\.dist-info)$""", + re.VERBOSE, + ) + + def __init__(self, filename: str) -> None: + """ + :raises InvalidWheelFilename: when the filename is invalid for a wheel + """ + wheel_info = self.wheel_file_re.match(filename) + if not wheel_info: + raise InvalidWheelFilename(f"{filename} is not a valid wheel filename.") + self.filename = filename + self.name = wheel_info.group("name").replace("_", "-") + # we'll assume "_" means "-" due to wheel naming scheme + # (https://github.com/pypa/pip/issues/1150) + self.version = wheel_info.group("ver").replace("_", "-") + self.build_tag = wheel_info.group("build") + self.pyversions = wheel_info.group("pyver").split(".") + self.abis = wheel_info.group("abi").split(".") + self.plats = wheel_info.group("plat").split(".") + + # All the tag combinations from this file + self.file_tags = { + Tag(x, y, z) for x in self.pyversions for y in self.abis for z in self.plats + } + + def get_formatted_file_tags(self) -> List[str]: + """Return the wheel's tags as a sorted list of strings.""" + return sorted(str(tag) for tag in self.file_tags) + + def support_index_min(self, tags: List[Tag]) -> int: + """Return the lowest index that one of the wheel's file_tag combinations + achieves in the given list of supported tags. + + For example, if there are 8 supported tags and one of the file tags + is first in the list, then return 0. + + :param tags: the PEP 425 tags to check the wheel against, in order + with most preferred first. + + :raises ValueError: If none of the wheel's file tags match one of + the supported tags. + """ + try: + return next(i for i, t in enumerate(tags) if t in self.file_tags) + except StopIteration: + raise ValueError() + + def find_most_preferred_tag( + self, tags: List[Tag], tag_to_priority: Dict[Tag, int] + ) -> int: + """Return the priority of the most preferred tag that one of the wheel's file + tag combinations achieves in the given list of supported tags using the given + tag_to_priority mapping, where lower priorities are more-preferred. + + This is used in place of support_index_min in some cases in order to avoid + an expensive linear scan of a large list of tags. + + :param tags: the PEP 425 tags to check the wheel against. + :param tag_to_priority: a mapping from tag to priority of that tag, where + lower is more preferred. + + :raises ValueError: If none of the wheel's file tags match one of + the supported tags. + """ + return min( + tag_to_priority[tag] for tag in self.file_tags if tag in tag_to_priority + ) + + def supported(self, tags: Iterable[Tag]) -> bool: + """Return whether the wheel is compatible with one of the given tags. + + :param tags: the PEP 425 tags to check the wheel against. + """ + return not self.file_tags.isdisjoint(tags) -- cgit v1.2.3-59-g8ed1b