Загрузить файлы в «venv/Lib/site-packages/pip/_internal/utils»
This commit is contained in:
201
venv/Lib/site-packages/pip/_internal/utils/compatibility_tags.py
Normal file
201
venv/Lib/site-packages/pip/_internal/utils/compatibility_tags.py
Normal file
@@ -0,0 +1,201 @@
|
||||
"""Generate and work with PEP 425 Compatibility Tags."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
|
||||
from pip._vendor.packaging.tags import (
|
||||
PythonVersion,
|
||||
Tag,
|
||||
android_platforms,
|
||||
compatible_tags,
|
||||
cpython_tags,
|
||||
generic_tags,
|
||||
interpreter_name,
|
||||
interpreter_version,
|
||||
ios_platforms,
|
||||
mac_platforms,
|
||||
)
|
||||
|
||||
_apple_arch_pat = re.compile(r"(.+)_(\d+)_(\d+)_(.+)")
|
||||
|
||||
|
||||
def version_info_to_nodot(version_info: tuple[int, ...]) -> str:
|
||||
# Only use up to the first two numbers.
|
||||
return "".join(map(str, version_info[:2]))
|
||||
|
||||
|
||||
def _mac_platforms(arch: str) -> list[str]:
|
||||
match = _apple_arch_pat.match(arch)
|
||||
if match:
|
||||
name, major, minor, actual_arch = match.groups()
|
||||
mac_version = (int(major), int(minor))
|
||||
arches = [
|
||||
# Since we have always only checked that the platform starts
|
||||
# with "macosx", for backwards-compatibility we extract the
|
||||
# actual prefix provided by the user in case they provided
|
||||
# something like "macosxcustom_". It may be good to remove
|
||||
# this as undocumented or deprecate it in the future.
|
||||
"{}_{}".format(name, arch[len("macosx_") :])
|
||||
for arch in mac_platforms(mac_version, actual_arch)
|
||||
]
|
||||
else:
|
||||
# arch pattern didn't match (?!)
|
||||
arches = [arch]
|
||||
return arches
|
||||
|
||||
|
||||
def _ios_platforms(arch: str) -> list[str]:
|
||||
match = _apple_arch_pat.match(arch)
|
||||
if match:
|
||||
name, major, minor, actual_multiarch = match.groups()
|
||||
ios_version = (int(major), int(minor))
|
||||
arches = [
|
||||
# Since we have always only checked that the platform starts
|
||||
# with "ios", for backwards-compatibility we extract the
|
||||
# actual prefix provided by the user in case they provided
|
||||
# something like "ioscustom_". It may be good to remove
|
||||
# this as undocumented or deprecate it in the future.
|
||||
"{}_{}".format(name, arch[len("ios_") :])
|
||||
for arch in ios_platforms(ios_version, actual_multiarch)
|
||||
]
|
||||
else:
|
||||
# arch pattern didn't match (?!)
|
||||
arches = [arch]
|
||||
return arches
|
||||
|
||||
|
||||
def _android_platforms(arch: str) -> list[str]:
|
||||
match = re.fullmatch(r"android_(\d+)_(.+)", arch)
|
||||
if match:
|
||||
api_level, abi = match.groups()
|
||||
return list(android_platforms(int(api_level), abi))
|
||||
else:
|
||||
# arch pattern didn't match (?!)
|
||||
return [arch]
|
||||
|
||||
|
||||
def _custom_manylinux_platforms(arch: str) -> list[str]:
|
||||
arches = [arch]
|
||||
arch_prefix, arch_sep, arch_suffix = arch.partition("_")
|
||||
if arch_prefix == "manylinux2014":
|
||||
# manylinux1/manylinux2010 wheels run on most manylinux2014 systems
|
||||
# with the exception of wheels depending on ncurses. PEP 599 states
|
||||
# manylinux1/manylinux2010 wheels should be considered
|
||||
# manylinux2014 wheels:
|
||||
# https://www.python.org/dev/peps/pep-0599/#backwards-compatibility-with-manylinux2010-wheels
|
||||
if arch_suffix in {"i686", "x86_64"}:
|
||||
arches.append("manylinux2010" + arch_sep + arch_suffix)
|
||||
arches.append("manylinux1" + arch_sep + arch_suffix)
|
||||
elif arch_prefix == "manylinux2010":
|
||||
# manylinux1 wheels run on most manylinux2010 systems with the
|
||||
# exception of wheels depending on ncurses. PEP 571 states
|
||||
# manylinux1 wheels should be considered manylinux2010 wheels:
|
||||
# https://www.python.org/dev/peps/pep-0571/#backwards-compatibility-with-manylinux1-wheels
|
||||
arches.append("manylinux1" + arch_sep + arch_suffix)
|
||||
return arches
|
||||
|
||||
|
||||
def _get_custom_platforms(arch: str) -> list[str]:
|
||||
arch_prefix, arch_sep, arch_suffix = arch.partition("_")
|
||||
if arch.startswith("macosx"):
|
||||
arches = _mac_platforms(arch)
|
||||
elif arch.startswith("ios"):
|
||||
arches = _ios_platforms(arch)
|
||||
elif arch_prefix == "android":
|
||||
arches = _android_platforms(arch)
|
||||
elif arch_prefix in ["manylinux2014", "manylinux2010"]:
|
||||
arches = _custom_manylinux_platforms(arch)
|
||||
else:
|
||||
arches = [arch]
|
||||
return arches
|
||||
|
||||
|
||||
def _expand_allowed_platforms(platforms: list[str] | None) -> list[str] | None:
|
||||
if not platforms:
|
||||
return None
|
||||
|
||||
seen = set()
|
||||
result = []
|
||||
|
||||
for p in platforms:
|
||||
if p in seen:
|
||||
continue
|
||||
additions = [c for c in _get_custom_platforms(p) if c not in seen]
|
||||
seen.update(additions)
|
||||
result.extend(additions)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def _get_python_version(version: str) -> PythonVersion:
|
||||
if len(version) > 1:
|
||||
return int(version[0]), int(version[1:])
|
||||
else:
|
||||
return (int(version[0]),)
|
||||
|
||||
|
||||
def _get_custom_interpreter(
|
||||
implementation: str | None = None, version: str | None = None
|
||||
) -> str:
|
||||
if implementation is None:
|
||||
implementation = interpreter_name()
|
||||
if version is None:
|
||||
version = interpreter_version()
|
||||
return f"{implementation}{version}"
|
||||
|
||||
|
||||
def get_supported(
|
||||
version: str | None = None,
|
||||
platforms: list[str] | None = None,
|
||||
impl: str | None = None,
|
||||
abis: list[str] | None = None,
|
||||
) -> list[Tag]:
|
||||
"""Return a list of supported tags for each version specified in
|
||||
`versions`.
|
||||
|
||||
:param version: a string version, of the form "33" or "32",
|
||||
or None. The version will be assumed to support our ABI.
|
||||
:param platform: specify a list of platforms you want valid
|
||||
tags for, or None. If None, use the local system platform.
|
||||
:param impl: specify the exact implementation you want valid
|
||||
tags for, or None. If None, use the local interpreter impl.
|
||||
:param abis: specify a list of abis you want valid
|
||||
tags for, or None. If None, use the local interpreter abi.
|
||||
"""
|
||||
supported: list[Tag] = []
|
||||
|
||||
python_version: PythonVersion | None = None
|
||||
if version is not None:
|
||||
python_version = _get_python_version(version)
|
||||
|
||||
interpreter = _get_custom_interpreter(impl, version)
|
||||
|
||||
platforms = _expand_allowed_platforms(platforms)
|
||||
|
||||
is_cpython = (impl or interpreter_name()) == "cp"
|
||||
if is_cpython:
|
||||
supported.extend(
|
||||
cpython_tags(
|
||||
python_version=python_version,
|
||||
abis=abis,
|
||||
platforms=platforms,
|
||||
)
|
||||
)
|
||||
else:
|
||||
supported.extend(
|
||||
generic_tags(
|
||||
interpreter=interpreter,
|
||||
abis=abis,
|
||||
platforms=platforms,
|
||||
)
|
||||
)
|
||||
supported.extend(
|
||||
compatible_tags(
|
||||
python_version=python_version,
|
||||
interpreter=interpreter,
|
||||
platforms=platforms,
|
||||
)
|
||||
)
|
||||
|
||||
return supported
|
||||
28
venv/Lib/site-packages/pip/_internal/utils/datetime.py
Normal file
28
venv/Lib/site-packages/pip/_internal/utils/datetime.py
Normal file
@@ -0,0 +1,28 @@
|
||||
"""For when pip wants to check the date or time."""
|
||||
|
||||
import datetime
|
||||
import sys
|
||||
|
||||
|
||||
def today_is_later_than(year: int, month: int, day: int) -> bool:
|
||||
today = datetime.date.today()
|
||||
given = datetime.date(year, month, day)
|
||||
|
||||
return today > given
|
||||
|
||||
|
||||
def parse_iso_datetime(isodate: str) -> datetime.datetime:
|
||||
"""Convert an ISO format string to a datetime.
|
||||
|
||||
Handles the format 2020-01-22T14:24:01Z (trailing Z)
|
||||
which is not supported by older versions of fromisoformat.
|
||||
"""
|
||||
# Python 3.11+ supports Z suffix natively in fromisoformat
|
||||
if sys.version_info >= (3, 11):
|
||||
return datetime.datetime.fromisoformat(isodate)
|
||||
else:
|
||||
return datetime.datetime.fromisoformat(
|
||||
isodate.replace("Z", "+00:00")
|
||||
if isodate.endswith("Z") and ("T" in isodate or " " in isodate.strip())
|
||||
else isodate
|
||||
)
|
||||
126
venv/Lib/site-packages/pip/_internal/utils/deprecation.py
Normal file
126
venv/Lib/site-packages/pip/_internal/utils/deprecation.py
Normal file
@@ -0,0 +1,126 @@
|
||||
"""
|
||||
A module that implements tooling to enable easy warnings about deprecations.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import warnings
|
||||
from typing import Any, TextIO
|
||||
|
||||
from pip._vendor.packaging.version import parse
|
||||
|
||||
from pip import __version__ as current_version # NOTE: tests patch this name.
|
||||
|
||||
DEPRECATION_MSG_PREFIX = "DEPRECATION: "
|
||||
|
||||
|
||||
class PipDeprecationWarning(Warning):
|
||||
pass
|
||||
|
||||
|
||||
_original_showwarning: Any = None
|
||||
|
||||
|
||||
# Warnings <-> Logging Integration
|
||||
def _showwarning(
|
||||
message: Warning | str,
|
||||
category: type[Warning],
|
||||
filename: str,
|
||||
lineno: int,
|
||||
file: TextIO | None = None,
|
||||
line: str | None = None,
|
||||
) -> None:
|
||||
if file is not None:
|
||||
if _original_showwarning is not None:
|
||||
_original_showwarning(message, category, filename, lineno, file, line)
|
||||
elif issubclass(category, PipDeprecationWarning):
|
||||
# We use a specially named logger which will handle all of the
|
||||
# deprecation messages for pip.
|
||||
logger = logging.getLogger("pip._internal.deprecations")
|
||||
logger.warning(message)
|
||||
else:
|
||||
_original_showwarning(message, category, filename, lineno, file, line)
|
||||
|
||||
|
||||
def install_warning_logger() -> None:
|
||||
# Enable our Deprecation Warnings
|
||||
warnings.simplefilter("default", PipDeprecationWarning, append=True)
|
||||
|
||||
global _original_showwarning
|
||||
|
||||
if _original_showwarning is None:
|
||||
_original_showwarning = warnings.showwarning
|
||||
warnings.showwarning = _showwarning
|
||||
|
||||
|
||||
def deprecated(
|
||||
*,
|
||||
reason: str,
|
||||
replacement: str | None,
|
||||
gone_in: str | None,
|
||||
feature_flag: str | None = None,
|
||||
issue: int | None = None,
|
||||
) -> None:
|
||||
"""Helper to deprecate existing functionality.
|
||||
|
||||
reason:
|
||||
Textual reason shown to the user about why this functionality has
|
||||
been deprecated. Should be a complete sentence.
|
||||
replacement:
|
||||
Textual suggestion shown to the user about what alternative
|
||||
functionality they can use.
|
||||
gone_in:
|
||||
The version of pip does this functionality should get removed in.
|
||||
Raises an error if pip's current version is greater than or equal to
|
||||
this.
|
||||
feature_flag:
|
||||
Command-line flag of the form --use-feature={feature_flag} for testing
|
||||
upcoming functionality.
|
||||
issue:
|
||||
Issue number on the tracker that would serve as a useful place for
|
||||
users to find related discussion and provide feedback.
|
||||
"""
|
||||
|
||||
# Determine whether or not the feature is already gone in this version.
|
||||
is_gone = gone_in is not None and parse(current_version) >= parse(gone_in)
|
||||
|
||||
message_parts = [
|
||||
(reason, f"{DEPRECATION_MSG_PREFIX}{{}}"),
|
||||
(
|
||||
gone_in,
|
||||
(
|
||||
"pip {} will enforce this behaviour change."
|
||||
if not is_gone
|
||||
else "Since pip {}, this is no longer supported."
|
||||
),
|
||||
),
|
||||
(
|
||||
replacement,
|
||||
"A possible replacement is {}.",
|
||||
),
|
||||
(
|
||||
feature_flag,
|
||||
(
|
||||
"You can use the flag --use-feature={} to test the upcoming behaviour."
|
||||
if not is_gone
|
||||
else None
|
||||
),
|
||||
),
|
||||
(
|
||||
issue,
|
||||
"Discussion can be found at https://github.com/pypa/pip/issues/{}",
|
||||
),
|
||||
]
|
||||
|
||||
message = " ".join(
|
||||
format_str.format(value)
|
||||
for value, format_str in message_parts
|
||||
if format_str is not None and value is not None
|
||||
)
|
||||
|
||||
# Raise as an error if this behaviour is deprecated.
|
||||
if is_gone:
|
||||
raise PipDeprecationWarning(message)
|
||||
|
||||
warnings.warn(message, category=PipDeprecationWarning, stacklevel=2)
|
||||
@@ -0,0 +1,87 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pip._internal.models.direct_url import ArchiveInfo, DirectUrl, DirInfo, VcsInfo
|
||||
from pip._internal.models.link import Link
|
||||
from pip._internal.utils.urls import path_to_url
|
||||
from pip._internal.vcs import vcs
|
||||
|
||||
|
||||
def direct_url_as_pep440_direct_reference(direct_url: DirectUrl, name: str) -> str:
|
||||
"""Convert a DirectUrl to a pip requirement string."""
|
||||
direct_url.validate() # if invalid, this is a pip bug
|
||||
requirement = name + " @ "
|
||||
fragments = []
|
||||
if isinstance(direct_url.info, VcsInfo):
|
||||
requirement += (
|
||||
f"{direct_url.info.vcs}+{direct_url.url}@{direct_url.info.commit_id}"
|
||||
)
|
||||
elif isinstance(direct_url.info, ArchiveInfo):
|
||||
requirement += direct_url.url
|
||||
if direct_url.info.hash:
|
||||
fragments.append(direct_url.info.hash)
|
||||
else:
|
||||
assert isinstance(direct_url.info, DirInfo)
|
||||
requirement += direct_url.url
|
||||
if direct_url.subdirectory:
|
||||
fragments.append("subdirectory=" + direct_url.subdirectory)
|
||||
if fragments:
|
||||
requirement += "#" + "&".join(fragments)
|
||||
return requirement
|
||||
|
||||
|
||||
def direct_url_for_editable(source_dir: str) -> DirectUrl:
|
||||
return DirectUrl(
|
||||
url=path_to_url(source_dir),
|
||||
info=DirInfo(editable=True),
|
||||
)
|
||||
|
||||
|
||||
def direct_url_from_link(
|
||||
link: Link, source_dir: str | None = None, link_is_in_wheel_cache: bool = False
|
||||
) -> DirectUrl:
|
||||
if link.is_vcs:
|
||||
vcs_backend = vcs.get_backend_for_scheme(link.scheme)
|
||||
assert vcs_backend
|
||||
url, requested_revision, _ = vcs_backend.get_url_rev_and_auth(
|
||||
link.url_without_fragment
|
||||
)
|
||||
# For VCS links, we need to find out and add commit_id.
|
||||
if link_is_in_wheel_cache:
|
||||
# If the requested VCS link corresponds to a cached
|
||||
# wheel, it means the requested revision was an
|
||||
# immutable commit hash, otherwise it would not have
|
||||
# been cached. In that case we don't have a source_dir
|
||||
# with the VCS checkout.
|
||||
assert requested_revision
|
||||
commit_id = requested_revision
|
||||
else:
|
||||
# If the wheel was not in cache, it means we have
|
||||
# had to checkout from VCS to build and we have a source_dir
|
||||
# which we can inspect to find out the commit id.
|
||||
assert source_dir
|
||||
commit_id = vcs_backend.get_revision(source_dir)
|
||||
return DirectUrl(
|
||||
url=url,
|
||||
info=VcsInfo(
|
||||
vcs=vcs_backend.name,
|
||||
commit_id=commit_id,
|
||||
requested_revision=requested_revision,
|
||||
),
|
||||
subdirectory=link.subdirectory_fragment,
|
||||
)
|
||||
elif link.is_existing_dir():
|
||||
return DirectUrl(
|
||||
url=link.url_without_fragment,
|
||||
info=DirInfo(),
|
||||
subdirectory=link.subdirectory_fragment,
|
||||
)
|
||||
else:
|
||||
hash = None
|
||||
hash_name = link.hash_name
|
||||
if hash_name:
|
||||
hash = f"{hash_name}={link.hash}"
|
||||
return DirectUrl(
|
||||
url=link.url_without_fragment,
|
||||
info=ArchiveInfo(hash=hash),
|
||||
subdirectory=link.subdirectory_fragment,
|
||||
)
|
||||
81
venv/Lib/site-packages/pip/_internal/utils/egg_link.py
Normal file
81
venv/Lib/site-packages/pip/_internal/utils/egg_link.py
Normal file
@@ -0,0 +1,81 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
from pip._internal.locations import site_packages, user_site
|
||||
from pip._internal.utils.virtualenv import (
|
||||
running_under_virtualenv,
|
||||
virtualenv_no_global,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
"egg_link_path_from_sys_path",
|
||||
"egg_link_path_from_location",
|
||||
]
|
||||
|
||||
|
||||
def _egg_link_names(raw_name: str) -> list[str]:
|
||||
"""
|
||||
Convert a Name metadata value to a .egg-link name, by applying
|
||||
the same substitution as pkg_resources's safe_name function.
|
||||
Note: we cannot use canonicalize_name because it has a different logic.
|
||||
|
||||
We also look for the raw name (without normalization) as setuptools 69 changed
|
||||
the way it names .egg-link files (https://github.com/pypa/setuptools/issues/4167).
|
||||
"""
|
||||
return [
|
||||
re.sub("[^A-Za-z0-9.]+", "-", raw_name) + ".egg-link",
|
||||
f"{raw_name}.egg-link",
|
||||
]
|
||||
|
||||
|
||||
def egg_link_path_from_sys_path(raw_name: str) -> str | None:
|
||||
"""
|
||||
Look for a .egg-link file for project name, by walking sys.path.
|
||||
"""
|
||||
egg_link_names = _egg_link_names(raw_name)
|
||||
for path_item in sys.path:
|
||||
for egg_link_name in egg_link_names:
|
||||
egg_link = os.path.join(path_item, egg_link_name)
|
||||
if os.path.isfile(egg_link):
|
||||
return egg_link
|
||||
return None
|
||||
|
||||
|
||||
def egg_link_path_from_location(raw_name: str) -> str | None:
|
||||
"""
|
||||
Return the path for the .egg-link file if it exists, otherwise, None.
|
||||
|
||||
There's 3 scenarios:
|
||||
1) not in a virtualenv
|
||||
try to find in site.USER_SITE, then site_packages
|
||||
2) in a no-global virtualenv
|
||||
try to find in site_packages
|
||||
3) in a yes-global virtualenv
|
||||
try to find in site_packages, then site.USER_SITE
|
||||
(don't look in global location)
|
||||
|
||||
For #1 and #3, there could be odd cases, where there's an egg-link in 2
|
||||
locations.
|
||||
|
||||
This method will just return the first one found.
|
||||
"""
|
||||
sites: list[str] = []
|
||||
if running_under_virtualenv():
|
||||
sites.append(site_packages)
|
||||
if not virtualenv_no_global() and user_site:
|
||||
sites.append(user_site)
|
||||
else:
|
||||
if user_site:
|
||||
sites.append(user_site)
|
||||
sites.append(site_packages)
|
||||
|
||||
egg_link_names = _egg_link_names(raw_name)
|
||||
for site in sites:
|
||||
for egg_link_name in egg_link_names:
|
||||
egglink = os.path.join(site, egg_link_name)
|
||||
if os.path.isfile(egglink):
|
||||
return egglink
|
||||
return None
|
||||
Reference in New Issue
Block a user