Spaces:
Runtime error
Runtime error
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"] | |
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 = [] | |
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): | |
# 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): | |
# type: (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] | |