Commit 52d7b45588f21c3298f49ac7faf21c3f3e0fd04e
1 parent
ea0a3cc6
Update ez_setup.py to the latest upstream revision
Source: Repo: git://github.com/pypa/setuptools.git Branch: bootstrap Commit: 0c3bf692236350f5c2c2cab5b235e9b6d3518fcb Notice: Line 39 remained unchanged, so the default version of setuptools is still `18.3.2` instead of `LATEST`.
Showing
1 changed file
with
67 additions
and
22 deletions
| @@ -3,6 +3,8 @@ | @@ -3,6 +3,8 @@ | ||
| 3 | """ | 3 | """ |
| 4 | Setuptools bootstrapping installer. | 4 | Setuptools bootstrapping installer. |
| 5 | 5 | ||
| 6 | +Maintained at https://github.com/pypa/setuptools/tree/bootstrap. | ||
| 7 | + | ||
| 6 | Run this script to install or upgrade setuptools. | 8 | Run this script to install or upgrade setuptools. |
| 7 | """ | 9 | """ |
| 8 | 10 | ||
| @@ -16,24 +18,30 @@ import subprocess | @@ -16,24 +18,30 @@ import subprocess | ||
| 16 | import platform | 18 | import platform |
| 17 | import textwrap | 19 | import textwrap |
| 18 | import contextlib | 20 | import contextlib |
| 19 | -import warnings | 21 | +import json |
| 22 | +import codecs | ||
| 20 | 23 | ||
| 21 | from distutils import log | 24 | from distutils import log |
| 22 | 25 | ||
| 23 | try: | 26 | try: |
| 24 | from urllib.request import urlopen | 27 | from urllib.request import urlopen |
| 28 | + from urllib.parse import urljoin | ||
| 25 | except ImportError: | 29 | except ImportError: |
| 26 | from urllib2 import urlopen | 30 | from urllib2 import urlopen |
| 31 | + from urlparse import urljoin | ||
| 27 | 32 | ||
| 28 | try: | 33 | try: |
| 29 | from site import USER_SITE | 34 | from site import USER_SITE |
| 30 | except ImportError: | 35 | except ImportError: |
| 31 | USER_SITE = None | 36 | USER_SITE = None |
| 32 | 37 | ||
| 38 | +LATEST = object() | ||
| 33 | DEFAULT_VERSION = "18.3.2" | 39 | DEFAULT_VERSION = "18.3.2" |
| 34 | -DEFAULT_URL = "https://pypi.python.org/packages/source/s/setuptools/" | 40 | +DEFAULT_URL = "https://pypi.io/packages/source/s/setuptools/" |
| 35 | DEFAULT_SAVE_DIR = os.curdir | 41 | DEFAULT_SAVE_DIR = os.curdir |
| 36 | 42 | ||
| 43 | +MEANINGFUL_INVALID_ZIP_ERR_MSG = 'Maybe {0} is corrupted, delete it and try again.' | ||
| 44 | + | ||
| 37 | 45 | ||
| 38 | def _python_cmd(*args): | 46 | def _python_cmd(*args): |
| 39 | """ | 47 | """ |
| @@ -98,8 +106,16 @@ def archive_context(filename): | @@ -98,8 +106,16 @@ def archive_context(filename): | ||
| 98 | old_wd = os.getcwd() | 106 | old_wd = os.getcwd() |
| 99 | try: | 107 | try: |
| 100 | os.chdir(tmpdir) | 108 | os.chdir(tmpdir) |
| 101 | - with ContextualZipFile(filename) as archive: | ||
| 102 | - archive.extractall() | 109 | + try: |
| 110 | + with ContextualZipFile(filename) as archive: | ||
| 111 | + archive.extractall() | ||
| 112 | + except zipfile.BadZipfile as err: | ||
| 113 | + if not err.args: | ||
| 114 | + err.args = ('', ) | ||
| 115 | + err.args = err.args + ( | ||
| 116 | + MEANINGFUL_INVALID_ZIP_ERR_MSG.format(filename), | ||
| 117 | + ) | ||
| 118 | + raise | ||
| 103 | 119 | ||
| 104 | # going in the directory | 120 | # going in the directory |
| 105 | subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0]) | 121 | subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0]) |
| @@ -114,18 +130,19 @@ def archive_context(filename): | @@ -114,18 +130,19 @@ def archive_context(filename): | ||
| 114 | 130 | ||
| 115 | def _do_download(version, download_base, to_dir, download_delay): | 131 | def _do_download(version, download_base, to_dir, download_delay): |
| 116 | """Download Setuptools.""" | 132 | """Download Setuptools.""" |
| 117 | - egg = os.path.join(to_dir, 'setuptools-%s-py%d.%d.egg' | ||
| 118 | - % (version, sys.version_info[0], sys.version_info[1])) | 133 | + py_desig = 'py{sys.version_info[0]}.{sys.version_info[1]}'.format(sys=sys) |
| 134 | + tp = 'setuptools-{version}-{py_desig}.egg' | ||
| 135 | + egg = os.path.join(to_dir, tp.format(**locals())) | ||
| 119 | if not os.path.exists(egg): | 136 | if not os.path.exists(egg): |
| 120 | archive = download_setuptools(version, download_base, | 137 | archive = download_setuptools(version, download_base, |
| 121 | - to_dir, download_delay) | 138 | + to_dir, download_delay) |
| 122 | _build_egg(egg, archive, to_dir) | 139 | _build_egg(egg, archive, to_dir) |
| 123 | sys.path.insert(0, egg) | 140 | sys.path.insert(0, egg) |
| 124 | 141 | ||
| 125 | # Remove previously-imported pkg_resources if present (see | 142 | # Remove previously-imported pkg_resources if present (see |
| 126 | # https://bitbucket.org/pypa/setuptools/pull-request/7/ for details). | 143 | # https://bitbucket.org/pypa/setuptools/pull-request/7/ for details). |
| 127 | if 'pkg_resources' in sys.modules: | 144 | if 'pkg_resources' in sys.modules: |
| 128 | - del sys.modules['pkg_resources'] | 145 | + _unload_pkg_resources() |
| 129 | 146 | ||
| 130 | import setuptools | 147 | import setuptools |
| 131 | setuptools.bootstrap_install_from = egg | 148 | setuptools.bootstrap_install_from = egg |
| @@ -140,6 +157,7 @@ def use_setuptools( | @@ -140,6 +157,7 @@ def use_setuptools( | ||
| 140 | Return None. Raise SystemExit if the requested version | 157 | Return None. Raise SystemExit if the requested version |
| 141 | or later cannot be installed. | 158 | or later cannot be installed. |
| 142 | """ | 159 | """ |
| 160 | + version = _resolve_version(version) | ||
| 143 | to_dir = os.path.abspath(to_dir) | 161 | to_dir = os.path.abspath(to_dir) |
| 144 | 162 | ||
| 145 | # prior to importing, capture the module state for | 163 | # prior to importing, capture the module state for |
| @@ -189,6 +207,11 @@ def _conflict_bail(VC_err, version): | @@ -189,6 +207,11 @@ def _conflict_bail(VC_err, version): | ||
| 189 | 207 | ||
| 190 | 208 | ||
| 191 | def _unload_pkg_resources(): | 209 | def _unload_pkg_resources(): |
| 210 | + sys.meta_path = [ | ||
| 211 | + importer | ||
| 212 | + for importer in sys.meta_path | ||
| 213 | + if importer.__class__.__module__ != 'pkg_resources.extern' | ||
| 214 | + ] | ||
| 192 | del_modules = [ | 215 | del_modules = [ |
| 193 | name for name in sys.modules | 216 | name for name in sys.modules |
| 194 | if name.startswith('pkg_resources') | 217 | if name.startswith('pkg_resources') |
| @@ -222,8 +245,8 @@ def download_file_powershell(url, target): | @@ -222,8 +245,8 @@ def download_file_powershell(url, target): | ||
| 222 | ps_cmd = ( | 245 | ps_cmd = ( |
| 223 | "[System.Net.WebRequest]::DefaultWebProxy.Credentials = " | 246 | "[System.Net.WebRequest]::DefaultWebProxy.Credentials = " |
| 224 | "[System.Net.CredentialCache]::DefaultCredentials; " | 247 | "[System.Net.CredentialCache]::DefaultCredentials; " |
| 225 | - "(new-object System.Net.WebClient).DownloadFile(%(url)r, %(target)r)" | ||
| 226 | - % vars() | 248 | + '(new-object System.Net.WebClient).DownloadFile("%(url)s", "%(target)s")' |
| 249 | + % locals() | ||
| 227 | ) | 250 | ) |
| 228 | cmd = [ | 251 | cmd = [ |
| 229 | 'powershell', | 252 | 'powershell', |
| @@ -248,7 +271,7 @@ download_file_powershell.viable = has_powershell | @@ -248,7 +271,7 @@ download_file_powershell.viable = has_powershell | ||
| 248 | 271 | ||
| 249 | 272 | ||
| 250 | def download_file_curl(url, target): | 273 | def download_file_curl(url, target): |
| 251 | - cmd = ['curl', url, '--silent', '--output', target] | 274 | + cmd = ['curl', url, '--location', '--silent', '--output', target] |
| 252 | _clean_check(cmd, target) | 275 | _clean_check(cmd, target) |
| 253 | 276 | ||
| 254 | 277 | ||
| @@ -321,6 +344,7 @@ def download_setuptools( | @@ -321,6 +344,7 @@ def download_setuptools( | ||
| 321 | ``downloader_factory`` should be a function taking no arguments and | 344 | ``downloader_factory`` should be a function taking no arguments and |
| 322 | returning a function for downloading a URL to a target. | 345 | returning a function for downloading a URL to a target. |
| 323 | """ | 346 | """ |
| 347 | + version = _resolve_version(version) | ||
| 324 | # making sure we use the absolute path | 348 | # making sure we use the absolute path |
| 325 | to_dir = os.path.abspath(to_dir) | 349 | to_dir = os.path.abspath(to_dir) |
| 326 | zip_name = "setuptools-%s.zip" % version | 350 | zip_name = "setuptools-%s.zip" % version |
| @@ -333,6 +357,27 @@ def download_setuptools( | @@ -333,6 +357,27 @@ def download_setuptools( | ||
| 333 | return os.path.realpath(saveto) | 357 | return os.path.realpath(saveto) |
| 334 | 358 | ||
| 335 | 359 | ||
| 360 | +def _resolve_version(version): | ||
| 361 | + """ | ||
| 362 | + Resolve LATEST version | ||
| 363 | + """ | ||
| 364 | + if version is not LATEST: | ||
| 365 | + return version | ||
| 366 | + | ||
| 367 | + meta_url = urljoin(DEFAULT_URL, '/pypi/setuptools/json') | ||
| 368 | + resp = urlopen(meta_url) | ||
| 369 | + with contextlib.closing(resp): | ||
| 370 | + try: | ||
| 371 | + charset = resp.info().get_content_charset() | ||
| 372 | + except Exception: | ||
| 373 | + # Python 2 compat; assume UTF-8 | ||
| 374 | + charset = 'UTF-8' | ||
| 375 | + reader = codecs.getreader(charset) | ||
| 376 | + doc = json.load(reader(resp)) | ||
| 377 | + | ||
| 378 | + return str(doc['info']['version']) | ||
| 379 | + | ||
| 380 | + | ||
| 336 | def _build_install_args(options): | 381 | def _build_install_args(options): |
| 337 | """ | 382 | """ |
| 338 | Build the arguments to 'python setup.py install' on the setuptools package. | 383 | Build the arguments to 'python setup.py install' on the setuptools package. |
| @@ -347,7 +392,7 @@ def _parse_args(): | @@ -347,7 +392,7 @@ def _parse_args(): | ||
| 347 | parser = optparse.OptionParser() | 392 | parser = optparse.OptionParser() |
| 348 | parser.add_option( | 393 | parser.add_option( |
| 349 | '--user', dest='user_install', action='store_true', default=False, | 394 | '--user', dest='user_install', action='store_true', default=False, |
| 350 | - help='install in user site package (requires Python 2.6 or later)') | 395 | + help='install in user site package') |
| 351 | parser.add_option( | 396 | parser.add_option( |
| 352 | '--download-base', dest='download_base', metavar="URL", | 397 | '--download-base', dest='download_base', metavar="URL", |
| 353 | default=DEFAULT_URL, | 398 | default=DEFAULT_URL, |
| @@ -362,9 +407,9 @@ def _parse_args(): | @@ -362,9 +407,9 @@ def _parse_args(): | ||
| 362 | default=DEFAULT_VERSION, | 407 | default=DEFAULT_VERSION, |
| 363 | ) | 408 | ) |
| 364 | parser.add_option( | 409 | parser.add_option( |
| 365 | - '--to-dir', | ||
| 366 | - help="Directory to save (and re-use) package", | ||
| 367 | - default=DEFAULT_SAVE_DIR, | 410 | + '--to-dir', |
| 411 | + help="Directory to save (and re-use) package", | ||
| 412 | + default=DEFAULT_SAVE_DIR, | ||
| 368 | ) | 413 | ) |
| 369 | options, args = parser.parse_args() | 414 | options, args = parser.parse_args() |
| 370 | # positional arguments are ignored | 415 | # positional arguments are ignored |
| @@ -372,13 +417,13 @@ def _parse_args(): | @@ -372,13 +417,13 @@ def _parse_args(): | ||
| 372 | 417 | ||
| 373 | 418 | ||
| 374 | def _download_args(options): | 419 | def _download_args(options): |
| 375 | - """Return args for download_setuptools function from cmdline args.""" | ||
| 376 | - return dict( | ||
| 377 | - version=options.version, | ||
| 378 | - download_base=options.download_base, | ||
| 379 | - downloader_factory=options.downloader_factory, | ||
| 380 | - to_dir=options.to_dir, | ||
| 381 | - ) | 420 | + """Return args for download_setuptools function from cmdline args.""" |
| 421 | + return dict( | ||
| 422 | + version=options.version, | ||
| 423 | + download_base=options.download_base, | ||
| 424 | + downloader_factory=options.downloader_factory, | ||
| 425 | + to_dir=options.to_dir, | ||
| 426 | + ) | ||
| 382 | 427 | ||
| 383 | 428 | ||
| 384 | def main(): | 429 | def main(): |
Please
register
or
login
to post a comment