Skip to content

Commit c419468

Browse files
author
stonebig
committed
pre-install pip via get-pip or ensurepip
finishing the wheel transition
1 parent f4d0e7d commit c419468

File tree

4 files changed

+124
-26
lines changed

4 files changed

+124
-26
lines changed

make.py

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ def get_package_fname(self, pattern):
304304
raise RuntimeError(
305305
'Could not found required package matching %s' % pattern)
306306

307-
def install_package(self, pattern):
307+
def install_package(self, pattern, install_options=None):
308308
"""Install package matching pattern"""
309309
fname = self.get_package_fname(pattern)
310310
if fname not in [p.fname for p in self.installed_packages]:
@@ -313,8 +313,11 @@ def install_package(self, pattern):
313313
self.distribution._print(pack, "Installing")
314314
self.distribution._print_done()
315315
else:
316-
self.distribution.install(pack,
317-
install_options=self.install_options)
316+
if install_options:
317+
self.distribution.install(pack, install_options)
318+
else:
319+
self.distribution.install(pack,
320+
install_options=self.install_options)
318321
self.installed_packages.append(pack)
319322

320323
def create_batch_script(self, name, contents):
@@ -362,8 +365,8 @@ def create_launcher(self, name, icon, command=None,
362365

363366
# handle well Flavor with R included
364367
data += [('R_HOME', '$EXEDIR%s' % r'\tools\R'),
365-
('JULIA_HOME','$EXEDIR\%s' % r'tools\Julia\bin'),
366-
('JULIA', '$EXEDIR\%s' % r'tools\Julia\bin\julia.exe')]
368+
('JULIA_HOME','$EXEDIR%s' % r'\tools\Julia\bin'),
369+
('JULIA', '$EXEDIR%s' % r'\tools\Julia\bin\julia.exe')]
367370

368371
if settingspath is not None:
369372
data += [('SETTINGSDIR', osp.dirname(settingspath)),
@@ -424,7 +427,8 @@ def _extract_python(self):
424427
os.mkdir(self.python_dir)
425428
utils.extract_msi(self.python_fname, targetdir=self.python_dir)
426429
os.remove(osp.join(self.python_dir, osp.basename(self.python_fname)))
427-
os.mkdir(osp.join(self.python_dir, 'Scripts'))
430+
if not os.path.exists(osp.join(self.python_dir, 'Scripts')):
431+
os.mkdir(osp.join(self.python_dir, 'Scripts'))
428432
self._print_done()
429433

430434
def _add_msvc_files(self):
@@ -469,18 +473,20 @@ def _install_required_packages(self):
469473
print("Installing required packages")
470474
self.install_package('pywin32-([0-9\.]*[a-z]*).%s-py%s.exe'
471475
% (self.py_arch, self.python_version))
472-
self.install_package('setuptools-([0-9\.]*[a-z]*[0-9]?).%s(-py%s)?.exe'
473-
% (self.py_arch, self.python_version))
474476
# Install First these two packages to support wheel format
475-
self.install_package('pip-([0-9\.]*[a-z]*[0-9]?).%s(-py%s)?.exe'
476-
% (self.py_arch, self.python_version))
477+
if self.python_version == '3.3':
478+
self.install_package('get-pip-([0-9\.]*[a-z]*[0-9]?).%s(-py%s)?.exe'
479+
% (self.py_arch, self.python_version))
480+
#else:
481+
self.install_package('%s-([0-9\.]*[a-z]*[0-9]?)(.*)(\.exe|\.whl)' %
482+
'setuptools' , install_options=['--upgrade','--no-deps'])
483+
self.install_package('%s-([0-9\.]*[a-z]*[0-9]?)(.*)(\.exe|\.whl)' %
484+
'pip', install_options=['--upgrade','--no-deps'])
485+
477486
self.install_package('wheel-([0-9\.]*[a-z]*[0-9]?).tar.gz')
478487
# six is needed early
479488
self.install_package('six-([0-9\.]*[a-z]*[0-9]?)-py2.py3-none-any.whl')
480489

481-
self.install_package(
482-
'spyder(lib)?-([0-9\.]*[a-z]*[0-9]?).%s(-py%s)?.exe'
483-
% (self.py_arch, self.python_version))
484490
# PyQt module is now like :PyQt4-4.10.4-gpl-Py3.4-Qt4.8.6-x32.exe
485491
self.install_package(
486492
'PyQt4-([0-9\.\-]*)-gpl-Py%s-Qt([0-9\.\-]*)%s.exe'
@@ -489,6 +495,10 @@ def _install_required_packages(self):
489495
'PyQwt-([0-9\.]*)-py%s-%s-([a-z0-9\.\-]*).exe'
490496
% (self.python_version, self.pyqt_arch))
491497

498+
self.install_package(
499+
'spyder(lib)?-([0-9\.]*[a-z]*[0-9]?).%s(-py%s)?.exe'
500+
% (self.py_arch, self.python_version))
501+
492502
# Install 'main packages' first (was before Wheel idea, keep for now)
493503
for happy_few in['numpy-MKL', 'scipy', 'matplotlib', 'pandas']:
494504
# can be a wheel now
@@ -1126,14 +1136,14 @@ def make_all(build_number, release_level, pyver,
11261136

11271137
#make_all(4, '', pyver='3.4', rootdir=r'D:\Winpython',
11281138
# verbose=False, archis=(32, ))
1129-
#make_all(4, '', pyver='3.4', rootdir=r'D:\Winpython',
1130-
# verbose=False, archis=(64, ), flavor='')
1139+
make_all(4, '', pyver='3.4', rootdir=r'D:\Winpython',
1140+
verbose=False, archis=(64, ), flavor='')
11311141
#make_all(5, '', pyver='3.3', rootdir=r'D:\Winpython',
11321142
# verbose=False, archis=(32, ))
11331143
#make_all(5, '', pyver='3.3', rootdir=r'D:\Winpython',
11341144
# verbose=False, archis=(64, ))
1135-
make_all(2, '', pyver='2.7', rootdir=r'D:\Winpython',
1136-
verbose=False, archis=(32, ))
1145+
#make_all(2, '', pyver='2.7', rootdir=r'D:\Winpython',
1146+
# verbose=False, archis=(32, ))
11371147
#make_all(2, '', pyver='2.7', rootdir=r'D:\Winpython',
11381148
# verbose=False, archis=(64, ))
11391149
#make_all(2, '', pyver='2.7', rootdir=r'D:\Winpython',

portable/launcher.nsi

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,12 @@ end_Rsettings:
7171

7272
; Addition of JULIA and JULIA_HOME Environment Variable if %JULIA% program exists
7373
StrCmp "${JULIA}" "" end_Julia_settings
74-
IfFileExists "${JULIA}\bin\*.*" 0 end_Julia_settings
74+
IfFileExists "${JULIA}" 0 end_Julia_settings
7575

7676
System::Call 'Kernel32::SetEnvironmentVariableA(t, t) i("JULIA", "${JULIA}").r0'
7777

7878
StrCmp "${JULIA_HOME}" "" end_Julia_settings
79+
IfFileExists "${JULIA_HOME}\*.*" 0 end_Julia_settings
7980
System::Call 'Kernel32::SetEnvironmentVariableA(t, t) i("JULIA_HOME", "${JULIA_HOME}").r0'
8081

8182
end_Julia_settings:

winpython/utils.py

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,33 @@ def get_python_long_version(path):
278278
ver = None
279279
return ver
280280

281+
# =============================================================================
282+
# Patch chebang line (courtesy of Christoph Gohlke)
283+
# =============================================================================
284+
def patch_shebang_line(fname, pad=b' '):
285+
"""Remove absolute path to python.exe in shebang lines."""
286+
if sys.version_info[0] == 2:
287+
shebang_line = re.compile(r"(#!.+pythonw?\.exe)") # Python2.7
288+
else:
289+
shebang_line = re.compile(b"(#!.+pythonw?\.exe)") # Python3+
290+
291+
with open(fname, 'rb') as fh:
292+
content = fh.read()
293+
294+
content = shebang_line.split(content, maxsplit=1)
295+
if len(content) != 3:
296+
return
297+
exe = os.path.basename(content[1][2:])
298+
content[1] = b'#!' + exe + (pad * (len(content[1]) - len(exe) - 2))
299+
content = b''.join(content)
300+
301+
try:
302+
with open(fname, 'wb') as fh:
303+
fh.write(content)
304+
print("patched", fname)
305+
except Exception:
306+
print("failed to patch", fname)
307+
281308

282309
# =============================================================================
283310
# Extract functions
@@ -302,6 +329,17 @@ def extract_msi(fname, targetdir=None, verbose=False):
302329
args += ['/qn']
303330
args += ['TARGETDIR=%s' % targetdir]
304331
subprocess.call([extract]+args, cwd=osp.dirname(fname))
332+
print ('fname=%s' % fname)
333+
print ('TARGETDIR=%s' % targetdir)
334+
# ensure pip if it's not 3.3
335+
if '-3.3' not in targetdir:
336+
subprocess.call([r'%s\%s' %(targetdir, 'python.exe'), '-m' , 'ensurepip'],
337+
cwd=osp.dirname(r'%s\%s' %(targetdir, 'pythons.exe')))
338+
# We patch ensurepip live (shame) !!!!
339+
# rational: https://github.com/pypa/pip/issues/2328
340+
import glob
341+
for fname in glob.glob(r'%s\Scripts\*.exe' % targetdir):
342+
patch_shebang_line(fname)
305343
return targetdir
306344

307345

@@ -354,7 +392,7 @@ def extract_archive(fname, targetdir=None, verbose=False):
354392
# . joblib-0.8.3_r1-py2.py3-none-any.whl,
355393
# . joblib-0.8.3-r1.tar.gz
356394

357-
SOURCE_PATTERN = r'([a-zA-Z0-9\-\_\.]*)-([0-9\.\_]*[a-z]*[0-9]?)(\.zip|\.tar\.gz|\-(py2|py2\.py3|py3)\-none\-any\.whl)'
395+
SOURCE_PATTERN = r'([a-zA-Z0-9\-\_\.]*)-([0-9\.\_]*[a-z]*[0-9]?)(\.zip|\.tar\.gz|\-(py[2-7]*|py[2-7]*\.py[2-7]*)\-none\-any\.whl)'
358396

359397
# WHEELBIN_PATTERN defines what an acceptable binary wheel package is
360398
# "cp([0-9]*)" to replace per cp(34) for python3.4
@@ -446,7 +484,8 @@ def build_wheel(this_whl, python_exe=None, copy_to=None,
446484
assert osp.isfile(python_exe)
447485
myroot = os.path.dirname(python_exe)
448486

449-
cmd = [python_exe, myroot + r'\Scripts\pip-script.py', 'install']
487+
#cmd = [python_exe, myroot + r'\Scripts\pip-script.py', 'install']
488+
cmd = [python_exe, '-m', 'pip', 'install']
450489
if install_options:
451490
cmd += install_options # typically ['--no-deps']
452491
print('wheel install_options', install_options)
@@ -469,7 +508,35 @@ def build_wheel(this_whl, python_exe=None, copy_to=None,
469508
print("Installed %s" % src_fname)
470509
return src_fname
471510

511+
def do_script(this_script, python_exe=None, copy_to=None,
512+
architecture=None, verbose=False, install_options=None):
513+
"""Execute a script (get-pip typically)"""
514+
if python_exe is None:
515+
python_exe = sys.executable
516+
assert osp.isfile(python_exe)
517+
myroot = os.path.dirname(python_exe)
518+
519+
#cmd = [python_exe, myroot + r'\Scripts\pip-script.py', 'install']
520+
cmd = [python_exe]
521+
if install_options:
522+
cmd += install_options # typically ['--no-deps']
523+
print('script install_options', install_options)
524+
cmd += [this_script]
525+
# print('build_wheel', myroot, cmd)
526+
print("Executing " , cmd)
472527

528+
if verbose:
529+
subprocess.call(cmd, cwd=myroot)
530+
else:
531+
p = subprocess.Popen(cmd, cwd=myroot, stdout=subprocess.PIPE,
532+
stderr=subprocess.PIPE)
533+
p.communicate()
534+
p.stdout.close()
535+
p.stderr.close()
536+
if verbose:
537+
print("Executed " % cmd)
538+
return 'ok'
539+
473540
def wheel_to_wininst(fname, python_exe=None,
474541
architecture=None, verbose=False, install_options=None):
475542
"""Just install a wheel !"""

winpython/wppm.py

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -372,19 +372,28 @@ def install(self, package, install_options=None):
372372

373373
# We patch pip live (around line 100) !!!!
374374
# rational: https://github.com/pypa/pip/issues/2328
375-
if package.name == "pip":
375+
if package.name == "get-pip":
376+
# self.exec_script
377+
my_script_is=osp.join(self.target, 'Scripts', 'get-pip.py')
378+
self.install_script(my_script_is, install_options=None)
379+
if package.name == "pip" or package.name == "get-pip":
380+
import glob
381+
for ffname in glob.glob(r'%s\Scripts\*.exe' % self.target):
382+
utils.patch_shebang_line(ffname)
376383
do_replace = self.target + (r"\Lib\site-packages\pip\_vendor" +
377384
r"\distlib\scripts.py" )
378385
print("do_replace" , do_replace)
379386
fh = open(do_replace,"r")
380387
the_thing = fh.read()
381388
fh.close()
382-
the_thing = the_thing.replace(
389+
the_thing_after = the_thing.replace(
383390
" executable = get_executable()",
384391
" executable = os.path.join(os.path.basename(get_executable()))")
385-
fh = open(do_replace,"w")
386-
fh.write(the_thing)
387-
fh.close()
392+
if not the_thing_after == the_thing:
393+
print("do_replace_ok" , do_replace)
394+
fh = open(do_replace,"w")
395+
fh.write(the_thing_after)
396+
fh.close()
388397

389398
def handle_specific_packages(self, package):
390399
"""Packages requiring additional configuration"""
@@ -474,7 +483,7 @@ def install_bdist_wininst(self, package):
474483
targetdir = utils.extract_archive(package.fname)
475484
self._print_done()
476485

477-
self._print(package, "Installing")
486+
self._print(package, "Installing %s from " % targetdir)
478487
self.copy_files(package, targetdir, 'PURELIB',
479488
osp.join('Lib', 'site-packages'))
480489
self.copy_files(package, targetdir, 'PLATLIB',
@@ -501,6 +510,17 @@ def install_bdist_wheel(self, package, install_options=None):
501510
package = Package(fname)
502511
self._print_done()
503512

513+
def install_script(self, script, install_options=None):
514+
try:
515+
fname = utils.do_script(script,
516+
python_exe=osp.join(self.target, 'python.exe'),
517+
architecture=self.architecture, verbose=self.verbose,
518+
install_options=install_options)
519+
except RuntimeError:
520+
if not self.verbose:
521+
print("Failed!")
522+
raise
523+
504524
def install_bdist_msi(self, package):
505525
"""Install a distutils package built with the bdist_msi option
506526
(binary distribution, .msi file)"""

0 commit comments

Comments
 (0)