@@ -1,4 +1,5 @@
"""PyPI and direct package downloading"""
"""PyPI and direct package downloading."""
import sys
import os
import re
Expand All
@@ -19,9 +20,20 @@
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
Expand All
@@ -40,15 +52,18 @@
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' ,
]
_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 ):
Expand Down
Expand Up
@@ -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 :
Expand All
@@ -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
Expand All
@@ -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 alternative interpretations of a source distro name
Expand All
@@ -178,9 +194,13 @@ def interpret_distro_name(
for p in range (1 , len (parts ) + 1 ):
yield Distribution (
location , metadata , '-' .join (parts [:p ]), '-' .join (parts [p :]),
py_version = py_version , precedence = precedence ,
platform = platform
location ,
metadata ,
'-' .join (parts [:p ]),
'-' .join (parts [p :]),
py_version = py_version ,
precedence = precedence ,
platform = platform ,
)
Expand All
@@ -197,8 +217,10 @@ def wrapper(*args, **kwargs):
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
Expand Down
Expand Up
@@ -282,11 +304,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 = {}
Expand Down
Expand Up
@@ -379,7 +406,8 @@ def url_ok(self, url, fatal=False):
return True
msg = (
"\n Note: 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 :
Expand Down
Expand Up
@@ -417,9 +445,7 @@ def _scan(self, link):
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
Expand Down
Expand Up
@@ -461,16 +487,15 @@ def process_index(self, url, page):
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 ):
Expand Down
Expand Up
@@ -501,9 +526,7 @@ def check_hash(self, checker, filename, tfp):
"""
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 )
Expand Down
Expand Up
@@ -540,7 +563,8 @@ def not_found_in_index(self, requirement):
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 ()
Expand Down
Expand Up
@@ -579,8 +603,14 @@ def download(self, spec, tmpdir):
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.
Expand Down
Expand Up
@@ -612,15 +642,13 @@ def find(req, env=None):
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
Expand Down
Expand Up
@@ -669,10 +697,15 @@ def fetch(self, requirement, tmpdir, force_scan=False, source=False):
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 )
Expand All
@@ -689,8 +722,9 @@ def gen_setup(self, filename, fragment, tmpdir):
"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
Expand Down
Expand Up
@@ -766,23 +800,22 @@ def open_url(self, url, warning=None): # noqa: C901 # is too complex (12)
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
Expand Down
Expand Up
@@ -887,10 +920,13 @@ def _download_git(self, url, filename):
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
Expand All
@@ -903,10 +939,13 @@ def _download_hg(self, url, filename):
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
Expand Down
Expand Up
@@ -1010,7 +1049,8 @@ def __init__(self):
@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 ()
]
Expand Down
Expand Up
@@ -1114,8 +1154,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 :
Expand Down