Skip to content

Commit 8acbcf6

Browse files
committed
Upgrade ez_setup to 3.6
1 parent 76ef9dd commit 8acbcf6

File tree

1 file changed

+65
-91
lines changed

1 file changed

+65
-91
lines changed

ez_setup.py

Lines changed: 65 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@
1717
import shutil
1818
import sys
1919
import tempfile
20-
import tarfile
20+
import zipfile
2121
import optparse
2222
import subprocess
2323
import platform
2424
import textwrap
25+
import contextlib
2526

2627
from distutils import log
2728

@@ -30,7 +31,7 @@
3031
except ImportError:
3132
USER_SITE = None
3233

33-
DEFAULT_VERSION = "2.2"
34+
DEFAULT_VERSION = "3.6"
3435
DEFAULT_URL = "https://pypi.python.org/packages/source/s/setuptools/"
3536

3637
def _python_cmd(*args):
@@ -40,70 +41,71 @@ def _python_cmd(*args):
4041
args = (sys.executable,) + args
4142
return subprocess.call(args) == 0
4243

43-
def _install(tarball, install_args=()):
44-
# extracting the tarball
45-
tmpdir = tempfile.mkdtemp()
46-
log.warn('Extracting in %s', tmpdir)
47-
old_wd = os.getcwd()
48-
try:
49-
os.chdir(tmpdir)
50-
tar = tarfile.open(tarball)
51-
_extractall(tar)
52-
tar.close()
53-
54-
# going in the directory
55-
subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
56-
os.chdir(subdir)
57-
log.warn('Now working in %s', subdir)
5844

45+
def _install(archive_filename, install_args=()):
46+
with archive_context(archive_filename):
5947
# installing
6048
log.warn('Installing Setuptools')
6149
if not _python_cmd('setup.py', 'install', *install_args):
6250
log.warn('Something went wrong during the installation.')
6351
log.warn('See the error message above.')
6452
# exitcode will be 2
6553
return 2
66-
finally:
67-
os.chdir(old_wd)
68-
shutil.rmtree(tmpdir)
6954

7055

71-
def _build_egg(egg, tarball, to_dir):
72-
# extracting the tarball
56+
def _build_egg(egg, archive_filename, to_dir):
57+
with archive_context(archive_filename):
58+
# building an egg
59+
log.warn('Building a Setuptools egg in %s', to_dir)
60+
_python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir)
61+
# returning the result
62+
log.warn(egg)
63+
if not os.path.exists(egg):
64+
raise IOError('Could not build the egg.')
65+
66+
67+
def get_zip_class():
68+
"""
69+
Supplement ZipFile class to support context manager for Python 2.6
70+
"""
71+
class ContextualZipFile(zipfile.ZipFile):
72+
def __enter__(self):
73+
return self
74+
def __exit__(self, type, value, traceback):
75+
self.close
76+
return zipfile.ZipFile if hasattr(zipfile.ZipFile, '__exit__') else \
77+
ContextualZipFile
78+
79+
80+
@contextlib.contextmanager
81+
def archive_context(filename):
82+
# extracting the archive
7383
tmpdir = tempfile.mkdtemp()
7484
log.warn('Extracting in %s', tmpdir)
7585
old_wd = os.getcwd()
7686
try:
7787
os.chdir(tmpdir)
78-
tar = tarfile.open(tarball)
79-
_extractall(tar)
80-
tar.close()
88+
with get_zip_class()(filename) as archive:
89+
archive.extractall()
8190

8291
# going in the directory
8392
subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
8493
os.chdir(subdir)
8594
log.warn('Now working in %s', subdir)
86-
87-
# building an egg
88-
log.warn('Building a Setuptools egg in %s', to_dir)
89-
_python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir)
95+
yield
9096

9197
finally:
9298
os.chdir(old_wd)
9399
shutil.rmtree(tmpdir)
94-
# returning the result
95-
log.warn(egg)
96-
if not os.path.exists(egg):
97-
raise IOError('Could not build the egg.')
98100

99101

100102
def _do_download(version, download_base, to_dir, download_delay):
101103
egg = os.path.join(to_dir, 'setuptools-%s-py%d.%d.egg'
102104
% (version, sys.version_info[0], sys.version_info[1]))
103105
if not os.path.exists(egg):
104-
tarball = download_setuptools(version, download_base,
106+
archive = download_setuptools(version, download_base,
105107
to_dir, download_delay)
106-
_build_egg(egg, tarball, to_dir)
108+
_build_egg(egg, archive, to_dir)
107109
sys.path.insert(0, egg)
108110

109111
# Remove previously-imported pkg_resources if present (see
@@ -116,7 +118,7 @@ def _do_download(version, download_base, to_dir, download_delay):
116118

117119

118120
def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
119-
to_dir=os.curdir, download_delay=15):
121+
to_dir=os.curdir, download_delay=15):
120122
to_dir = os.path.abspath(to_dir)
121123
rep_modules = 'pkg_resources', 'setuptools'
122124
imported = set(sys.modules).intersection(rep_modules)
@@ -164,10 +166,16 @@ def download_file_powershell(url, target):
164166
trust). Raise an exception if the command cannot complete.
165167
"""
166168
target = os.path.abspath(target)
169+
ps_cmd = (
170+
"[System.Net.WebRequest]::DefaultWebProxy.Credentials = "
171+
"[System.Net.CredentialCache]::DefaultCredentials; "
172+
"(new-object System.Net.WebClient).DownloadFile(%(url)r, %(target)r)"
173+
% vars()
174+
)
167175
cmd = [
168176
'powershell',
169177
'-Command',
170-
"(new-object System.Net.WebClient).DownloadFile(%(url)r, %(target)r)" % vars(),
178+
ps_cmd,
171179
]
172180
_clean_check(cmd, target)
173181

@@ -179,7 +187,7 @@ def has_powershell():
179187
try:
180188
try:
181189
subprocess.check_call(cmd, stdout=devnull, stderr=devnull)
182-
except:
190+
except Exception:
183191
return False
184192
finally:
185193
devnull.close()
@@ -197,7 +205,7 @@ def has_curl():
197205
try:
198206
try:
199207
subprocess.check_call(cmd, stdout=devnull, stderr=devnull)
200-
except:
208+
except Exception:
201209
return False
202210
finally:
203211
devnull.close()
@@ -215,7 +223,7 @@ def has_wget():
215223
try:
216224
try:
217225
subprocess.check_call(cmd, stdout=devnull, stderr=devnull)
218-
except:
226+
except Exception:
219227
return False
220228
finally:
221229
devnull.close()
@@ -261,9 +269,9 @@ def get_best_downloader():
261269
return dl
262270

263271
def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
264-
to_dir=os.curdir, delay=15,
265-
downloader_factory=get_best_downloader):
266-
"""Download setuptools from a specified location and return its filename
272+
to_dir=os.curdir, delay=15, downloader_factory=get_best_downloader):
273+
"""
274+
Download setuptools from a specified location and return its filename
267275
268276
`version` should be a valid setuptools version number that is available
269277
as an egg for download under the `download_base` URL (which should end
@@ -276,56 +284,15 @@ def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
276284
"""
277285
# making sure we use the absolute path
278286
to_dir = os.path.abspath(to_dir)
279-
tgz_name = "setuptools-%s.tar.gz" % version
280-
url = download_base + tgz_name
281-
saveto = os.path.join(to_dir, tgz_name)
287+
zip_name = "setuptools-%s.zip" % version
288+
url = download_base + zip_name
289+
saveto = os.path.join(to_dir, zip_name)
282290
if not os.path.exists(saveto): # Avoid repeated downloads
283291
log.warn("Downloading %s", url)
284292
downloader = downloader_factory()
285293
downloader(url, saveto)
286294
return os.path.realpath(saveto)
287295

288-
289-
def _extractall(self, path=".", members=None):
290-
"""Extract all members from the archive to the current working
291-
directory and set owner, modification time and permissions on
292-
directories afterwards. `path' specifies a different directory
293-
to extract to. `members' is optional and must be a subset of the
294-
list returned by getmembers().
295-
"""
296-
import copy
297-
import operator
298-
from tarfile import ExtractError
299-
directories = []
300-
301-
if members is None:
302-
members = self
303-
304-
for tarinfo in members:
305-
if tarinfo.isdir():
306-
# Extract directories with a safe mode.
307-
directories.append(tarinfo)
308-
tarinfo = copy.copy(tarinfo)
309-
tarinfo.mode = 448 # decimal for oct 0700
310-
self.extract(tarinfo, path)
311-
312-
# Reverse sort directories.
313-
directories.sort(key=operator.attrgetter('name'), reverse=True)
314-
315-
# Set correct owner, mtime and filemode on directories.
316-
for tarinfo in directories:
317-
dirpath = os.path.join(path, tarinfo.name)
318-
try:
319-
self.chown(tarinfo, dirpath)
320-
self.utime(tarinfo, dirpath)
321-
self.chmod(tarinfo, dirpath)
322-
except ExtractError as e:
323-
if self.errorlevel > 1:
324-
raise
325-
else:
326-
self._dbg(1, "tarfile: %s" % e)
327-
328-
329296
def _build_install_args(options):
330297
"""
331298
Build the arguments to 'python setup.py install' on the setuptools package
@@ -349,16 +316,23 @@ def _parse_args():
349316
const=lambda: download_file_insecure, default=get_best_downloader,
350317
help='Use internal, non-validating downloader'
351318
)
319+
parser.add_option(
320+
'--version', help="Specify which version to download",
321+
default=DEFAULT_VERSION,
322+
)
352323
options, args = parser.parse_args()
353324
# positional arguments are ignored
354325
return options
355326

356-
def main(version=DEFAULT_VERSION):
327+
def main():
357328
"""Install or upgrade setuptools and EasyInstall"""
358329
options = _parse_args()
359-
tarball = download_setuptools(download_base=options.download_base,
360-
downloader_factory=options.downloader_factory)
361-
return _install(tarball, _build_install_args(options))
330+
archive = download_setuptools(
331+
version=options.version,
332+
download_base=options.download_base,
333+
downloader_factory=options.downloader_factory,
334+
)
335+
return _install(archive, _build_install_args(options))
362336

363337
if __name__ == '__main__':
364338
sys.exit(main())

0 commit comments

Comments
 (0)