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