Including the venv
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
"""A package that contains models that represent entities.
|
||||
"""
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,36 @@
|
||||
from pip._vendor.packaging.version import parse as parse_version
|
||||
|
||||
from pip._internal.utils.models import KeyBasedCompareMixin
|
||||
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
|
||||
|
||||
if MYPY_CHECK_RUNNING:
|
||||
from pip._vendor.packaging.version import _BaseVersion
|
||||
from pip._internal.models.link import Link
|
||||
from typing import Any
|
||||
|
||||
|
||||
class InstallationCandidate(KeyBasedCompareMixin):
|
||||
"""Represents a potential "candidate" for installation.
|
||||
"""
|
||||
|
||||
def __init__(self, project, version, link):
|
||||
# type: (Any, str, Link) -> None
|
||||
self.project = project
|
||||
self.version = parse_version(version) # type: _BaseVersion
|
||||
self.link = link
|
||||
|
||||
super(InstallationCandidate, self).__init__(
|
||||
key=(self.project, self.version, self.link),
|
||||
defining_class=InstallationCandidate
|
||||
)
|
||||
|
||||
def __repr__(self):
|
||||
# type: () -> str
|
||||
return "<InstallationCandidate({!r}, {!r}, {!r})>".format(
|
||||
self.project, self.version, self.link,
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return '{!r} candidate (version {} at {})'.format(
|
||||
self.project, self.version, self.link,
|
||||
)
|
@@ -0,0 +1,73 @@
|
||||
from pip._vendor.packaging.utils import canonicalize_name
|
||||
|
||||
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
|
||||
|
||||
if MYPY_CHECK_RUNNING:
|
||||
from typing import Optional, Set, FrozenSet
|
||||
|
||||
|
||||
class FormatControl(object):
|
||||
"""Helper for managing formats from which a package can be installed.
|
||||
"""
|
||||
|
||||
def __init__(self, no_binary=None, only_binary=None):
|
||||
# type: (Optional[Set], Optional[Set]) -> 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):
|
||||
return self.__dict__ == other.__dict__
|
||||
|
||||
def __ne__(self, other):
|
||||
return not self.__eq__(other)
|
||||
|
||||
def __repr__(self):
|
||||
return "{}({}, {})".format(
|
||||
self.__class__.__name__,
|
||||
self.no_binary,
|
||||
self.only_binary
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def handle_mutual_excludes(value, target, other):
|
||||
# type: (str, Optional[Set], Optional[Set]) -> None
|
||||
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):
|
||||
# type: (str) -> FrozenSet
|
||||
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):
|
||||
# type: () -> None
|
||||
self.handle_mutual_excludes(
|
||||
':all:', self.no_binary, self.only_binary,
|
||||
)
|
31
lib/python3.8/site-packages/pip/_internal/models/index.py
Normal file
31
lib/python3.8/site-packages/pip/_internal/models/index.py
Normal file
@@ -0,0 +1,31 @@
|
||||
from pip._vendor.six.moves.urllib import parse as urllib_parse
|
||||
|
||||
|
||||
class PackageIndex(object):
|
||||
"""Represents a Package Index and provides easier access to endpoints
|
||||
"""
|
||||
|
||||
def __init__(self, url, file_storage_domain):
|
||||
# type: (str, str) -> None
|
||||
super(PackageIndex, self).__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):
|
||||
# type: (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'
|
||||
)
|
213
lib/python3.8/site-packages/pip/_internal/models/link.py
Normal file
213
lib/python3.8/site-packages/pip/_internal/models/link.py
Normal file
@@ -0,0 +1,213 @@
|
||||
import posixpath
|
||||
import re
|
||||
|
||||
from pip._vendor.six.moves.urllib import parse as urllib_parse
|
||||
|
||||
from pip._internal.utils.misc import (
|
||||
WHEEL_EXTENSION, path_to_url, redact_password_from_url,
|
||||
split_auth_from_netloc, splitext,
|
||||
)
|
||||
from pip._internal.utils.models import KeyBasedCompareMixin
|
||||
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
|
||||
|
||||
if MYPY_CHECK_RUNNING:
|
||||
from typing import Optional, Text, Tuple, Union
|
||||
from pip._internal.index import HTMLPage
|
||||
from pip._internal.utils.hashes import Hashes
|
||||
|
||||
|
||||
class Link(KeyBasedCompareMixin):
|
||||
"""Represents a parsed link from a Package Index's simple URL
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
url, # type: str
|
||||
comes_from=None, # type: Optional[Union[str, HTMLPage]]
|
||||
requires_python=None, # type: Optional[str]
|
||||
yanked_reason=None, # type: Optional[Text]
|
||||
):
|
||||
# type: (...) -> None
|
||||
"""
|
||||
:param url: url of the resource pointed to (href of the link)
|
||||
:param comes_from: instance of HTMLPage 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.
|
||||
"""
|
||||
|
||||
# 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.comes_from = comes_from
|
||||
self.requires_python = requires_python if requires_python else None
|
||||
self.yanked_reason = yanked_reason
|
||||
|
||||
super(Link, self).__init__(key=url, defining_class=Link)
|
||||
|
||||
def __str__(self):
|
||||
if self.requires_python:
|
||||
rp = ' (requires-python:%s)' % self.requires_python
|
||||
else:
|
||||
rp = ''
|
||||
if self.comes_from:
|
||||
return '%s (from %s)%s' % (redact_password_from_url(self._url),
|
||||
self.comes_from, rp)
|
||||
else:
|
||||
return redact_password_from_url(str(self._url))
|
||||
|
||||
def __repr__(self):
|
||||
return '<Link %s>' % self
|
||||
|
||||
@property
|
||||
def url(self):
|
||||
# type: () -> str
|
||||
return self._url
|
||||
|
||||
@property
|
||||
def filename(self):
|
||||
# type: () -> 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, ('URL %r produced no filename' % self._url)
|
||||
return name
|
||||
|
||||
@property
|
||||
def scheme(self):
|
||||
# type: () -> str
|
||||
return self._parsed_url.scheme
|
||||
|
||||
@property
|
||||
def netloc(self):
|
||||
# type: () -> str
|
||||
"""
|
||||
This can contain auth information.
|
||||
"""
|
||||
return self._parsed_url.netloc
|
||||
|
||||
@property
|
||||
def path(self):
|
||||
# type: () -> str
|
||||
return urllib_parse.unquote(self._parsed_url.path)
|
||||
|
||||
def splitext(self):
|
||||
# type: () -> Tuple[str, str]
|
||||
return splitext(posixpath.basename(self.path.rstrip('/')))
|
||||
|
||||
@property
|
||||
def ext(self):
|
||||
# type: () -> str
|
||||
return self.splitext()[1]
|
||||
|
||||
@property
|
||||
def url_without_fragment(self):
|
||||
# type: () -> str
|
||||
scheme, netloc, path, query, fragment = self._parsed_url
|
||||
return urllib_parse.urlunsplit((scheme, netloc, path, query, None))
|
||||
|
||||
_egg_fragment_re = re.compile(r'[#&]egg=([^&]*)')
|
||||
|
||||
@property
|
||||
def egg_fragment(self):
|
||||
# type: () -> 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):
|
||||
# type: () -> Optional[str]
|
||||
match = self._subdirectory_fragment_re.search(self._url)
|
||||
if not match:
|
||||
return None
|
||||
return match.group(1)
|
||||
|
||||
_hash_re = re.compile(
|
||||
r'(sha1|sha224|sha384|sha256|sha512|md5)=([a-f0-9]+)'
|
||||
)
|
||||
|
||||
@property
|
||||
def hash(self):
|
||||
# type: () -> Optional[str]
|
||||
match = self._hash_re.search(self._url)
|
||||
if match:
|
||||
return match.group(2)
|
||||
return None
|
||||
|
||||
@property
|
||||
def hash_name(self):
|
||||
# type: () -> Optional[str]
|
||||
match = self._hash_re.search(self._url)
|
||||
if match:
|
||||
return match.group(1)
|
||||
return None
|
||||
|
||||
@property
|
||||
def show_url(self):
|
||||
# type: () -> Optional[str]
|
||||
return posixpath.basename(self._url.split('#', 1)[0].split('?', 1)[0])
|
||||
|
||||
@property
|
||||
def is_wheel(self):
|
||||
# type: () -> bool
|
||||
return self.ext == WHEEL_EXTENSION
|
||||
|
||||
@property
|
||||
def is_artifact(self):
|
||||
# type: () -> bool
|
||||
"""
|
||||
Determines if this points to an actual artifact (e.g. a tarball) or if
|
||||
it points to an "abstract" thing like a path or a VCS location.
|
||||
"""
|
||||
from pip._internal.vcs import vcs
|
||||
|
||||
if self.scheme in vcs.all_schemes:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
@property
|
||||
def is_yanked(self):
|
||||
# type: () -> bool
|
||||
return self.yanked_reason is not None
|
||||
|
||||
@property
|
||||
def has_hash(self):
|
||||
return self.hash_name is not None
|
||||
|
||||
def is_hash_allowed(self, hashes):
|
||||
# type: (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)
|
113
lib/python3.8/site-packages/pip/_internal/models/search_scope.py
Normal file
113
lib/python3.8/site-packages/pip/_internal/models/search_scope.py
Normal file
@@ -0,0 +1,113 @@
|
||||
import itertools
|
||||
import logging
|
||||
import os
|
||||
import posixpath
|
||||
|
||||
from pip._vendor.packaging.utils import canonicalize_name
|
||||
from pip._vendor.six.moves.urllib import parse as urllib_parse
|
||||
|
||||
from pip._internal.models.index import PyPI
|
||||
from pip._internal.utils.compat import HAS_TLS
|
||||
from pip._internal.utils.misc import normalize_path, redact_password_from_url
|
||||
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
|
||||
|
||||
if MYPY_CHECK_RUNNING:
|
||||
from typing import List
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SearchScope(object):
|
||||
|
||||
"""
|
||||
Encapsulates the locations that pip is configured to search.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def create(
|
||||
cls,
|
||||
find_links, # type: List[str]
|
||||
index_urls, # type: List[str]
|
||||
):
|
||||
# type: (...) -> 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 = [] # type: 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, # type: List[str]
|
||||
index_urls, # type: List[str]
|
||||
):
|
||||
# type: (...) -> None
|
||||
self.find_links = find_links
|
||||
self.index_urls = index_urls
|
||||
|
||||
def get_formatted_locations(self):
|
||||
# type: () -> str
|
||||
lines = []
|
||||
if self.index_urls and self.index_urls != [PyPI.simple_url]:
|
||||
lines.append(
|
||||
'Looking in indexes: {}'.format(', '.join(
|
||||
redact_password_from_url(url) for url in self.index_urls))
|
||||
)
|
||||
if self.find_links:
|
||||
lines.append(
|
||||
'Looking in links: {}'.format(', '.join(
|
||||
redact_password_from_url(url) for url in self.find_links))
|
||||
)
|
||||
return '\n'.join(lines)
|
||||
|
||||
def get_index_urls_locations(self, project_name):
|
||||
# type: (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):
|
||||
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]
|
@@ -0,0 +1,47 @@
|
||||
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
|
||||
|
||||
if MYPY_CHECK_RUNNING:
|
||||
from typing import Optional
|
||||
from pip._internal.models.format_control import FormatControl
|
||||
|
||||
|
||||
class SelectionPreferences(object):
|
||||
|
||||
"""
|
||||
Encapsulates the candidate selection preferences for downloading
|
||||
and installing files.
|
||||
"""
|
||||
|
||||
# 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, # type: bool
|
||||
allow_all_prereleases=False, # type: bool
|
||||
format_control=None, # type: Optional[FormatControl]
|
||||
prefer_binary=False, # type: bool
|
||||
ignore_requires_python=None, # type: Optional[bool]
|
||||
):
|
||||
# type: (...) -> 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
|
@@ -0,0 +1,106 @@
|
||||
import sys
|
||||
|
||||
from pip._internal.pep425tags import get_supported, version_info_to_nodot
|
||||
from pip._internal.utils.misc import normalize_version_info
|
||||
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
|
||||
|
||||
if MYPY_CHECK_RUNNING:
|
||||
from typing import List, Optional, Tuple
|
||||
from pip._internal.pep425tags import Pep425Tag
|
||||
|
||||
|
||||
class TargetPython(object):
|
||||
|
||||
"""
|
||||
Encapsulates the properties of a Python interpreter one is targeting
|
||||
for a package install, download, etc.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
platform=None, # type: Optional[str]
|
||||
py_version_info=None, # type: Optional[Tuple[int, ...]]
|
||||
abi=None, # type: Optional[str]
|
||||
implementation=None, # type: Optional[str]
|
||||
):
|
||||
# type: (...) -> None
|
||||
"""
|
||||
:param platform: A string or None. If None, searches for packages
|
||||
that are supported by the current system. Otherwise, will find
|
||||
packages that can be built on the platform 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 abi: A string or None. This is passed to pep425tags.py's
|
||||
get_supported() function as is.
|
||||
:param implementation: A string or None. This is passed to
|
||||
pep425tags.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.abi = abi
|
||||
self.implementation = implementation
|
||||
self.platform = platform
|
||||
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 = None # type: Optional[List[Pep425Tag]]
|
||||
|
||||
def format_given(self):
|
||||
# type: () -> 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 = [
|
||||
('platform', self.platform),
|
||||
('version_info', display_version),
|
||||
('abi', self.abi),
|
||||
('implementation', self.implementation),
|
||||
]
|
||||
return ' '.join(
|
||||
'{}={!r}'.format(key, value) for key, value in key_values
|
||||
if value is not None
|
||||
)
|
||||
|
||||
def get_tags(self):
|
||||
# type: () -> List[Pep425Tag]
|
||||
"""
|
||||
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:
|
||||
versions = None
|
||||
else:
|
||||
versions = [version_info_to_nodot(py_version_info)]
|
||||
|
||||
tags = get_supported(
|
||||
versions=versions,
|
||||
platform=self.platform,
|
||||
abi=self.abi,
|
||||
impl=self.implementation,
|
||||
)
|
||||
self._valid_tags = tags
|
||||
|
||||
return self._valid_tags
|
Reference in New Issue
Block a user