summaryrefslogtreecommitdiff
path: root/setuptools/package_index.py
diff options
context:
space:
mode:
authorJason R. Coombs <jaraco@jaraco.com>2023-01-14 11:13:55 -0500
committerJason R. Coombs <jaraco@jaraco.com>2023-01-14 11:13:55 -0500
commit245da5441248eeb2d575034d04cbc241bf545161 (patch)
treed76526e1461252cc1119cd9482a64ef1e75f7838 /setuptools/package_index.py
parentd7b783a4b8b01e58135e40bd9a1db8a82c090982 (diff)
parent82eee6a998251b33ab3984f39b25c27ca72ba8b0 (diff)
downloadpython-setuptools-git-245da5441248eeb2d575034d04cbc241bf545161.tar.gz
Merge branch 'main' into debt/remove-legacy-version
Diffstat (limited to 'setuptools/package_index.py')
-rw-r--r--setuptools/package_index.py173
1 files changed, 106 insertions, 67 deletions
diff --git a/setuptools/package_index.py b/setuptools/package_index.py
index 24a7f306..bec41835 100644
--- a/setuptools/package_index.py
+++ b/setuptools/package_index.py
@@ -1,4 +1,5 @@
-"""PyPI and direct package downloading"""
+"""PyPI and direct package downloading."""
+
import sys
import os
import re
@@ -19,9 +20,20 @@ from functools import wraps
import setuptools
from pkg_resources import (
- CHECKOUT_DIST, Distribution, BINARY_DIST, normalize_path, SOURCE_DIST,
- Environment, find_distributions, safe_name, safe_version,
- to_filename, Requirement, DEVELOP_DIST, EGG_DIST, parse_version,
+ CHECKOUT_DIST,
+ Distribution,
+ BINARY_DIST,
+ normalize_path,
+ SOURCE_DIST,
+ Environment,
+ find_distributions,
+ safe_name,
+ safe_version,
+ to_filename,
+ Requirement,
+ DEVELOP_DIST,
+ EGG_DIST,
+ parse_version,
)
from distutils import log
from distutils.errors import DistutilsError
@@ -40,7 +52,9 @@ URL_SCHEME = re.compile('([-+.a-z0-9]{2,}):', re.I).match
EXTENSIONS = ".tar.gz .tar.bz2 .tar .zip .tgz".split()
__all__ = [
- 'PackageIndex', 'distros_for_url', 'parse_bdist_wininst',
+ 'PackageIndex',
+ 'distros_for_url',
+ 'parse_bdist_wininst',
'interpret_distro_name',
]
@@ -48,7 +62,8 @@ _SOCKET_TIMEOUT = 15
_tmpl = "setuptools/{setuptools.__version__} Python-urllib/{py_major}"
user_agent = _tmpl.format(
- py_major='{}.{}'.format(*sys.version_info), setuptools=setuptools)
+ py_major='{}.{}'.format(*sys.version_info), setuptools=setuptools
+)
def parse_requirement_arg(spec):
@@ -120,13 +135,15 @@ def distros_for_location(location, basename, metadata=None):
wheel = Wheel(basename)
if not wheel.is_compatible():
return []
- return [Distribution(
- location=location,
- project_name=wheel.project_name,
- version=wheel.version,
- # Increase priority over eggs.
- precedence=EGG_DIST + 1,
- )]
+ return [
+ Distribution(
+ location=location,
+ project_name=wheel.project_name,
+ version=wheel.version,
+ # Increase priority over eggs.
+ precedence=EGG_DIST + 1,
+ )
+ ]
if basename.endswith('.exe'):
win_base, py_ver, platform = parse_bdist_wininst(basename)
if win_base is not None:
@@ -137,7 +154,7 @@ def distros_for_location(location, basename, metadata=None):
#
for ext in EXTENSIONS:
if basename.endswith(ext):
- basename = basename[:-len(ext)]
+ basename = basename[: -len(ext)]
return interpret_distro_name(location, basename, metadata)
return [] # no extension matched
@@ -150,8 +167,7 @@ def distros_for_filename(filename, metadata=None):
def interpret_distro_name(
- location, basename, metadata, py_version=None, precedence=SOURCE_DIST,
- platform=None
+ location, basename, metadata, py_version=None, precedence=SOURCE_DIST, platform=None
):
"""Generate the interpretation of a source distro name
@@ -174,8 +190,12 @@ def interpret_distro_name(
p = len(parts)
yield Distribution(
- location, metadata, '-'.join(parts[:p]), '-'.join(parts[p:]),
- py_version=py_version, precedence=precedence,
+ location,
+ metadata,
+ '-'.join(parts[:p]),
+ '-'.join(parts[p:]),
+ py_version=py_version,
+ precedence=precedence,
platform=platform
)
@@ -193,8 +213,10 @@ def unique_values(func):
return wrapper
-REL = re.compile(r"""<([^>]*\srel\s*=\s*['"]?([^'">]+)[^>]*)>""", re.I)
-# this line is here to fix emacs' cruddy broken syntax highlighting
+REL = re.compile(r"""<([^>]*\srel\s{0,10}=\s{0,10}['"]?([^'" >]+)[^>]*)>""", re.I)
+"""
+Regex for an HTML tag with 'rel="val"' attributes.
+"""
@unique_values
@@ -278,11 +300,16 @@ class PackageIndex(Environment):
"""A distribution index that scans web pages for download URLs"""
def __init__(
- self, index_url="https://pypi.org/simple/", hosts=('*',),
- ca_bundle=None, verify_ssl=True, *args, **kw
+ self,
+ index_url="https://pypi.org/simple/",
+ hosts=('*',),
+ ca_bundle=None,
+ verify_ssl=True,
+ *args,
+ **kw
):
super().__init__(*args, **kw)
- self.index_url = index_url + "/" [:not index_url.endswith('/')]
+ self.index_url = index_url + "/"[: not index_url.endswith('/')]
self.scanned_urls = {}
self.fetched_urls = {}
self.package_pages = {}
@@ -375,7 +402,8 @@ class PackageIndex(Environment):
return True
msg = (
"\nNote: Bypassing %s (disallowed host; see "
- "http://bit.ly/2hrImnY for details).\n")
+ "http://bit.ly/2hrImnY for details).\n"
+ )
if fatal:
raise DistutilsError(msg % url)
else:
@@ -413,9 +441,7 @@ class PackageIndex(Environment):
if not link.startswith(self.index_url):
return NO_MATCH_SENTINEL
- parts = list(map(
- urllib.parse.unquote, link[len(self.index_url):].split('/')
- ))
+ parts = list(map(urllib.parse.unquote, link[len(self.index_url) :].split('/')))
if len(parts) != 2 or '#' in parts[1]:
return NO_MATCH_SENTINEL
@@ -457,16 +483,15 @@ class PackageIndex(Environment):
def need_version_info(self, url):
self.scan_all(
"Page at %s links to .py file(s) without version info; an index "
- "scan is required.", url
+ "scan is required.",
+ url,
)
def scan_all(self, msg=None, *args):
if self.index_url not in self.fetched_urls:
if msg:
self.warn(msg, *args)
- self.info(
- "Scanning index of all packages (this may take a while)"
- )
+ self.info("Scanning index of all packages (this may take a while)")
self.scan_url(self.index_url)
def find_packages(self, requirement):
@@ -497,9 +522,7 @@ class PackageIndex(Environment):
"""
checker is a ContentChecker
"""
- checker.report(
- self.debug,
- "Validating %%s checksum for %s" % filename)
+ checker.report(self.debug, "Validating %%s checksum for %s" % filename)
if not checker.is_valid():
tfp.close()
os.unlink(filename)
@@ -536,7 +559,8 @@ class PackageIndex(Environment):
else: # no distros seen for this name, might be misspelled
meth, msg = (
self.warn,
- "Couldn't find index page for %r (maybe misspelled?)")
+ "Couldn't find index page for %r (maybe misspelled?)",
+ )
meth(msg, requirement.unsafe_name)
self.scan_all()
@@ -575,8 +599,14 @@ class PackageIndex(Environment):
return getattr(self.fetch_distribution(spec, tmpdir), 'location', None)
def fetch_distribution( # noqa: C901 # is too complex (14) # FIXME
- self, requirement, tmpdir, force_scan=False, source=False,
- develop_ok=False, local_index=None):
+ self,
+ requirement,
+ tmpdir,
+ force_scan=False,
+ source=False,
+ develop_ok=False,
+ local_index=None,
+ ):
"""Obtain a distribution suitable for fulfilling `requirement`
`requirement` must be a ``pkg_resources.Requirement`` instance.
@@ -608,15 +638,13 @@ class PackageIndex(Environment):
if dist.precedence == DEVELOP_DIST and not develop_ok:
if dist not in skipped:
self.warn(
- "Skipping development or system egg: %s", dist,
+ "Skipping development or system egg: %s",
+ dist,
)
skipped[dist] = 1
continue
- test = (
- dist in req
- and (dist.precedence <= SOURCE_DIST or not source)
- )
+ test = dist in req and (dist.precedence <= SOURCE_DIST or not source)
if test:
loc = self.download(dist.location, tmpdir)
dist.download_location = loc
@@ -665,10 +693,15 @@ class PackageIndex(Environment):
def gen_setup(self, filename, fragment, tmpdir):
match = EGG_FRAGMENT.match(fragment)
- dists = match and [
- d for d in
- interpret_distro_name(filename, match.group(1), None) if d.version
- ] or []
+ dists = (
+ match
+ and [
+ d
+ for d in interpret_distro_name(filename, match.group(1), None)
+ if d.version
+ ]
+ or []
+ )
if len(dists) == 1: # unambiguous ``#egg`` fragment
basename = os.path.basename(filename)
@@ -676,8 +709,7 @@ class PackageIndex(Environment):
# Make sure the file has been downloaded to the temp dir.
if os.path.dirname(filename) != tmpdir:
dst = os.path.join(tmpdir, basename)
- from setuptools.command.easy_install import samefile
- if not samefile(filename, dst):
+ if not (os.path.exists(dst) and os.path.samefile(filename, dst)):
shutil.copy2(filename, dst)
filename = dst
@@ -686,8 +718,9 @@ class PackageIndex(Environment):
"from setuptools import setup\n"
"setup(name=%r, version=%r, py_modules=[%r])\n"
% (
- dists[0].project_name, dists[0].version,
- os.path.splitext(basename)[0]
+ dists[0].project_name,
+ dists[0].version,
+ os.path.splitext(basename)[0],
)
)
return filename
@@ -763,23 +796,22 @@ class PackageIndex(Environment):
if warning:
self.warn(warning, v.reason)
else:
- raise DistutilsError("Download error for %s: %s"
- % (url, v.reason)) from v
+ raise DistutilsError(
+ "Download error for %s: %s" % (url, v.reason)
+ ) from v
except http.client.BadStatusLine as v:
if warning:
self.warn(warning, v.line)
else:
raise DistutilsError(
'%s returned a bad status line. The server might be '
- 'down, %s' %
- (url, v.line)
+ 'down, %s' % (url, v.line)
) from v
except (http.client.HTTPException, socket.error) as v:
if warning:
self.warn(warning, v)
else:
- raise DistutilsError("Download error for %s: %s"
- % (url, v)) from v
+ raise DistutilsError("Download error for %s: %s" % (url, v)) from v
def _download_url(self, scheme, url, tmpdir):
# Determine download filename
@@ -884,10 +916,13 @@ class PackageIndex(Environment):
if rev is not None:
self.info("Checking out %s", rev)
- os.system("git -C %s checkout --quiet %s" % (
- filename,
- rev,
- ))
+ os.system(
+ "git -C %s checkout --quiet %s"
+ % (
+ filename,
+ rev,
+ )
+ )
return filename
@@ -900,10 +935,13 @@ class PackageIndex(Environment):
if rev is not None:
self.info("Updating to %s", rev)
- os.system("hg --cwd %s up -C -r %s -q" % (
- filename,
- rev,
- ))
+ os.system(
+ "hg --cwd %s up -C -r %s -q"
+ % (
+ filename,
+ rev,
+ )
+ )
return filename
@@ -1007,7 +1045,8 @@ class PyPIConfig(configparser.RawConfigParser):
@property
def creds_by_repository(self):
sections_with_repositories = [
- section for section in self.sections()
+ section
+ for section in self.sections()
if self.get(section, 'repository').strip()
]
@@ -1111,8 +1150,8 @@ def local_open(url):
files.append('<a href="{name}">{name}</a>'.format(name=f))
else:
tmpl = (
- "<html><head><title>{url}</title>"
- "</head><body>{files}</body></html>")
+ "<html><head><title>{url}</title>" "</head><body>{files}</body></html>"
+ )
body = tmpl.format(url=url, files='\n'.join(files))
status, message = 200, "OK"
else: