| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850 |
- # -*- coding: utf-8 -*-
- #
- # Copyright © 2012 Pierre Raybaut
- # Licensed under the terms of the MIT License
- # (see winpython/__init__.py for details)
- """
- WinPython utilities
- Created on Tue Aug 14 14:08:40 2012
- """
- from __future__ import print_function
- import os
- import os.path as osp
- import subprocess
- import re
- import tarfile
- import zipfile
- import tempfile
- import shutil
- import atexit
- import sys
- import stat
- import locale
- # Local imports
- from winpython.py3compat import winreg
- def onerror(function, path, excinfo):
- """Error handler for `shutil.rmtree`.
- If the error is due to an access error (read-only file), it
- attempts to add write permission and then retries.
- If the error is for another reason, it re-raises the error.
- Usage: `shutil.rmtree(path, onerror=onerror)"""
- if not os.access(path, os.W_OK):
- # Is the error an access error?
- os.chmod(path, stat.S_IWUSR)
- function(path)
- else:
- raise
- # Exact copy of 'spyderlib.utils.programs.is_program_installed' function
- def is_program_installed(basename):
- """Return program absolute path if installed in PATH
- Otherwise, return None"""
- for path in os.environ["PATH"].split(os.pathsep):
- abspath = osp.join(path, basename)
- if osp.isfile(abspath):
- return abspath
- # =============================================================================
- # Environment variables
- # =============================================================================
- def get_env(name, current=True):
- """Return HKCU/HKLM environment variable name and value
- For example, get_user_env('PATH') may returns:
- ('Path', u'C:\\Program Files\\Intel\\WiFi\\bin\\')"""
- root = (
- winreg.HKEY_CURRENT_USER
- if current
- else winreg.HKEY_LOCAL_MACHINE
- )
- key = winreg.OpenKey(root, "Environment")
- for index in range(0, winreg.QueryInfoKey(key)[1]):
- try:
- value = winreg.EnumValue(key, index)
- if value[0].lower() == name.lower():
- # Return both value[0] and value[1] because value[0] could be
- # different from name (lowercase/uppercase)
- return value[0], value[1]
- except:
- break
- def set_env(name, value, current=True):
- """Set HKCU/HKLM environment variables"""
- root = (
- winreg.HKEY_CURRENT_USER
- if current
- else winreg.HKEY_LOCAL_MACHINE
- )
- key = winreg.OpenKey(root, "Environment")
- try:
- _x, key_type = winreg.QueryValueEx(key, name)
- except WindowsError:
- key_type = winreg.REG_EXPAND_SZ
- key = winreg.OpenKey(
- root, "Environment", 0, winreg.KEY_SET_VALUE
- )
- winreg.SetValueEx(key, name, 0, key_type, value)
- from win32gui import SendMessageTimeout
- from win32con import (
- HWND_BROADCAST,
- WM_SETTINGCHANGE,
- SMTO_ABORTIFHUNG,
- )
- SendMessageTimeout(
- HWND_BROADCAST,
- WM_SETTINGCHANGE,
- 0,
- "Environment",
- SMTO_ABORTIFHUNG,
- 5000,
- )
- #==============================================================================
- # https://stackoverflow.com/questions/580924/how-to-access-a-files-properties-on-windows
- def getFileProperties(fname):
- #==============================================================================
- """
- Read all properties of the given file return them as a dictionary.
- """
- import win32api
- propNames = ('Comments', 'InternalName', 'ProductName',
- 'CompanyName', 'LegalCopyright', 'ProductVersion',
- 'FileDescription', 'LegalTrademarks', 'PrivateBuild',
- 'FileVersion', 'OriginalFilename', 'SpecialBuild')
- props = {'FixedFileInfo': None, 'StringFileInfo': None, 'FileVersion': None}
- try:
- # backslash as parm returns dictionary of numeric info corresponding to VS_FIXEDFILEINFO struc
- fixedInfo = win32api.GetFileVersionInfo(fname, '\\')
- props['FixedFileInfo'] = fixedInfo
- props['FileVersion'] = "%d.%d.%d.%d" % (fixedInfo['FileVersionMS'] / 65536,
- fixedInfo['FileVersionMS'] % 65536, fixedInfo['FileVersionLS'] / 65536,
- fixedInfo['FileVersionLS'] % 65536)
- # \VarFileInfo\Translation returns list of available (language, codepage)
- # pairs that can be used to retreive string info. We are using only the first pair.
- lang, codepage = win32api.GetFileVersionInfo(fname, '\\VarFileInfo\\Translation')[0]
- # any other must be of the form \StringfileInfo\%04X%04X\parm_name, middle
- # two are language/codepage pair returned from above
- strInfo = {}
- for propName in propNames:
- strInfoPath = u'\\StringFileInfo\\%04X%04X\\%s' % (lang, codepage, propName)
- ## print str_info
- strInfo[propName] = win32api.GetFileVersionInfo(fname, strInfoPath)
- props['StringFileInfo'] = strInfo
- except:
- pass
- return props
- # =============================================================================
- # Shortcuts, start menu
- # =============================================================================
- def get_special_folder_path(path_name):
- """Return special folder path"""
- from win32com.shell import shell, shellcon
- for maybe in """
- CSIDL_COMMON_STARTMENU CSIDL_STARTMENU CSIDL_COMMON_APPDATA
- CSIDL_LOCAL_APPDATA CSIDL_APPDATA CSIDL_COMMON_DESKTOPDIRECTORY
- CSIDL_DESKTOPDIRECTORY CSIDL_COMMON_STARTUP CSIDL_STARTUP
- CSIDL_COMMON_PROGRAMS CSIDL_PROGRAMS CSIDL_PROGRAM_FILES_COMMON
- CSIDL_PROGRAM_FILES CSIDL_FONTS""".split():
- if maybe == path_name:
- csidl = getattr(shellcon, maybe)
- return shell.SHGetSpecialFolderPath(
- 0, csidl, False
- )
- raise ValueError(
- "%s is an unknown path ID" % (path_name,)
- )
- def get_winpython_start_menu_folder(current=True):
- """Return WinPython Start menu shortcuts folder"""
- if current:
- # non-admin install - always goes in this user's start menu.
- folder = get_special_folder_path("CSIDL_PROGRAMS")
- else:
- try:
- folder = get_special_folder_path(
- "CSIDL_COMMON_PROGRAMS"
- )
- except OSError:
- # No CSIDL_COMMON_PROGRAMS on this platform
- folder = get_special_folder_path(
- "CSIDL_PROGRAMS"
- )
- return osp.join(folder, 'WinPython')
- def create_winpython_start_menu_folder(current=True):
- """Create WinPython Start menu folder -- remove it if it already exists"""
- path = get_winpython_start_menu_folder(current=current)
- if osp.isdir(path):
- try:
- shutil.rmtree(path, onerror=onerror)
- except WindowsError:
- print(
- "Directory %s could not be removed" % path,
- file=sys.stderr,
- )
- else:
- os.mkdir(path)
- return path
- def create_shortcut(
- path,
- description,
- filename,
- arguments="",
- workdir="",
- iconpath="",
- iconindex=0,
- ):
- """Create Windows shortcut (.lnk file)"""
- import pythoncom
- from win32com.shell import shell
- ilink = pythoncom.CoCreateInstance(
- shell.CLSID_ShellLink,
- None,
- pythoncom.CLSCTX_INPROC_SERVER,
- shell.IID_IShellLink,
- )
- ilink.SetPath(path)
- ilink.SetDescription(description)
- if arguments:
- ilink.SetArguments(arguments)
- if workdir:
- ilink.SetWorkingDirectory(workdir)
- if iconpath or iconindex:
- ilink.SetIconLocation(iconpath, iconindex)
- # now save it.
- ipf = ilink.QueryInterface(pythoncom.IID_IPersistFile)
- if not filename.endswith('.lnk'):
- filename += '.lnk'
- ipf.Save(filename, 0)
- # =============================================================================
- # Misc.
- # =============================================================================
- def print_box(text):
- """Print text in a box"""
- line0 = "+" + ("-" * (len(text) + 2)) + "+"
- line1 = "| " + text + " |"
- print(
- ("\n\n" + "\n".join([line0, line1, line0]) + "\n")
- )
- def is_python_distribution(path):
- """Return True if path is a Python distribution"""
- # XXX: This test could be improved but it seems to be sufficient
- return osp.isfile(
- osp.join(path, 'python.exe')
- ) and osp.isdir(osp.join(path, 'Lib', 'site-packages'))
- # =============================================================================
- # Shell, Python queries
- # =============================================================================
- def decode_fs_string(string):
- """Convert string from file system charset to unicode"""
- charset = sys.getfilesystemencoding()
- if charset is None:
- charset = locale.getpreferredencoding()
- return string.decode(charset)
- def exec_shell_cmd(args, path):
- """Execute shell command (*args* is a list of arguments) in *path*"""
- # print " ".join(args)
- process = subprocess.Popen(
- args,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- cwd=path,
- shell=True,
- )
- return decode_fs_string(process.stdout.read())
- def exec_run_cmd(args, path=None):
- """run a single command (*args* is a list of arguments) in optional *path*"""
- # only applicable to Python-3.5+
- # python-3.7+ allows to replace "stdout and stderr ", per "capture_output=True"
- if path:
- process = subprocess.run(args,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- cwd=path)
- else:
- process = subprocess.run(args,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- return decode_fs_string(process.stdout)
- def get_r_version(path):
- """Return version of the R installed in *path*"""
- return (
- exec_shell_cmd('dir ..\README.R*', path)
- .splitlines()[-3]
- .split("-")[-1]
- )
- def get_julia_version(path):
- """Return version of the Julia installed in *path*"""
- return (
- exec_shell_cmd('julia.exe -v', path)
- .splitlines()[0]
- .split(" ")[-1]
- )
- def get_nodejs_version(path):
- """Return version of the Nodejs installed in *path*"""
- return exec_shell_cmd('node -v', path).splitlines()[0]
- def get_npmjs_version(path):
- """Return version of the Nodejs installed in *path*"""
- return exec_shell_cmd('npm -v', path).splitlines()[0]
- def get_pandoc_version(path):
- """Return version of the Pandoc executable in *path*"""
- return (
- exec_shell_cmd('pandoc -v', path)
- .splitlines()[0]
- .split(" ")[-1]
- )
- def python_query(cmd, path):
- """Execute Python command using the Python interpreter located in *path*"""
- return exec_shell_cmd(
- 'python -c "%s"' % cmd, path
- ).splitlines()[0]
- def get_python_infos(path):
- """Return (version, architecture) for the Python distribution located in
- *path*. The version number is limited to MAJOR.MINOR, the architecture is
- an integer: 32 or 64"""
- is_64 = python_query(
- 'import sys; print(sys.maxsize > 2**32)', path
- )
- arch = {'True': 64, 'False': 32}.get(is_64, None)
- ver = python_query(
- "import sys; print('%d.%d' % (sys.version_info.major, "
- "sys.version_info.minor))",
- path,
- )
- if re.match(r'([0-9]*)\.([0-9]*)', ver) is None:
- ver = None
- return ver, arch
- def get_python_long_version(path):
- """Return long version (X.Y.Z) for the Python distribution located in
- *path*"""
- ver = python_query(
- "import sys; print('%d.%d.%d' % "
- "(sys.version_info.major, sys.version_info.minor,"
- "sys.version_info.micro))",
- path,
- )
- if (
- re.match(r'([0-9]*)\.([0-9]*)\.([0-9]*)', ver)
- is None
- ):
- ver = None
- return ver
- # =============================================================================
- # Patch chebang line (courtesy of Christoph Gohlke)
- # =============================================================================
- def patch_shebang_line(
- fname, pad=b' ', to_movable=True, targetdir=""
- ):
- """Remove absolute path to python.exe in shebang lines, or re-add it"""
- import re
- import sys
- import os
- target_dir = targetdir # movable option
- if to_movable == False:
- target_dir = os.path.abspath(os.path.dirname(fname))
- target_dir = (
- os.path.abspath(os.path.join(target_dir, r'..'))
- + '\\'
- )
- executable = sys.executable
- if sys.version_info[0] == 2:
- shebang_line = re.compile(
- r"(#!.*pythonw?\.exe)"
- ) # Python2.7
- else:
- shebang_line = re.compile(
- b"(#!.*pythonw?\.exe)"
- ) # Python3+
- target_dir = target_dir.encode('utf-8')
- with open(fname, 'rb') as fh:
- initial_content = fh.read()
- fh.close
- fh = None
- content = shebang_line.split(
- initial_content, maxsplit=1
- )
- if len(content) != 3:
- return
- exe = os.path.basename(content[1][2:])
- content[1] = (
- b'#!' + target_dir + exe
- ) # + (pad * (len(content[1]) - len(exe) - 2))
- final_content = b''.join(content)
- if initial_content == final_content:
- return
- try:
- with open(fname, 'wb') as fo:
- fo.write(final_content)
- fo.close
- fo = None
- print("patched", fname)
- except Exception:
- print("failed to patch", fname)
- # =============================================================================
- # Patch shebang line in .py files
- # =============================================================================
- def patch_shebang_line_py(
- fname, to_movable=True, targetdir=""
- ):
- """Changes shebang line in '.py' file to relative or absolue path"""
- import fileinput
- import re
- import sys
- if sys.version_info[0] == 2:
- # Python 2.x doesn't create .py files for .exe files. So, Moving
- # WinPython doesn't break running executable files.
- return
- if to_movable:
- exec_path = '#!.\python.exe'
- else:
- exec_path = '#!' + sys.executable
- for line in fileinput.input(fname, inplace=True):
- if re.match('^#\!.*python\.exe$', line) is not None:
- print(exec_path)
- else:
- print(line, end='')
- # =============================================================================
- # Patch sourcefile (instead of forking packages)
- # =============================================================================
- def patch_sourcefile(
- fname, in_text, out_text, silent_mode=False
- ):
- """Replace a string in a source file"""
- import io
- if osp.isfile(fname) and not in_text == out_text:
- with io.open(fname, 'r') as fh:
- content = fh.read()
- new_content = content.replace(in_text, out_text)
- if not new_content == content:
- if not silent_mode:
- print(
- "patching ",
- fname,
- "from",
- in_text,
- "to",
- out_text,
- )
- with io.open(fname, 'wt') as fh:
- fh.write(new_content)
- # =============================================================================
- # Patch sourcelines (instead of forking packages)
- # =============================================================================
- def patch_sourcelines(
- fname,
- in_line_start,
- out_line,
- endline='\n',
- silent_mode=False,
- ):
- """Replace the middle of lines between in_line_start and endline """
- import io
- import os.path as osp
- if osp.isfile(fname):
- with io.open(fname, 'r') as fh:
- contents = fh.readlines()
- content = "".join(contents)
- for l in range(len(contents)):
- if contents[l].startswith(in_line_start):
- begining, middle = (
- in_line_start,
- contents[l][len(in_line_start) :],
- )
- ending = ""
- if middle.find(endline) > 0:
- ending = endline + endline.join(
- middle.split(endline)[1:]
- )
- middle = middle.split(endline)[0]
- middle = out_line
- new_line = begining + middle + ending
- if not new_line == contents[l]:
- if not silent_mode:
- print(
- "patching ",
- fname,
- " from\n",
- contents[l],
- "\nto\n",
- new_line,
- )
- contents[l] = new_line
- new_content = "".join(contents)
- if not new_content == content:
- # if not silent_mode:
- # print("patching ", fname, "from", content, "to", new_content)
- with io.open(fname, 'wt') as fh:
- try:
- fh.write(new_content)
- except:
- print(
- "impossible to patch",
- fname,
- "from",
- content,
- "to",
- new_content,
- )
- # =============================================================================
- # Extract functions
- # =============================================================================
- def _create_temp_dir():
- """Create a temporary directory and remove it at exit"""
- tmpdir = tempfile.mkdtemp(prefix='wppm_')
- atexit.register(
- lambda path: shutil.rmtree(path, onerror=onerror),
- tmpdir,
- )
- return tmpdir
- def extract_exe(fname, targetdir=None, verbose=False):
- """Extract .exe archive to a temporary directory (if targetdir
- is None). Return the temporary directory path"""
- if targetdir is None:
- targetdir = _create_temp_dir()
- extract = '7z.exe'
- assert is_program_installed(extract), (
- "Required program '%s' was not found" % extract
- )
- bname = osp.basename(fname)
- args = ['x', '-o%s' % targetdir, '-aos', bname]
- if verbose:
- retcode = subprocess.call(
- [extract] + args, cwd=osp.dirname(fname)
- )
- else:
- p = subprocess.Popen(
- [extract] + args,
- cwd=osp.dirname(fname),
- stdout=subprocess.PIPE,
- )
- p.communicate()
- p.stdout.close()
- retcode = p.returncode
- if retcode != 0:
- raise RuntimeError(
- "Failed to extract %s (return code: %d)"
- % (fname, retcode)
- )
- return targetdir
- def extract_archive(fname, targetdir=None, verbose=False):
- """Extract .zip, .exe (considered to be a zip archive) or .tar.gz archive
- to a temporary directory (if targetdir is None).
- Return the temporary directory path"""
- if targetdir is None:
- targetdir = _create_temp_dir()
- else:
- try:
- os.mkdir(targetdir)
- except:
- pass
- if osp.splitext(fname)[1] in ('.zip', '.exe'):
- obj = zipfile.ZipFile(fname, mode="r")
- elif fname.endswith('.tar.gz'):
- obj = tarfile.open(fname, mode='r:gz')
- else:
- raise RuntimeError(
- "Unsupported archive filename %s" % fname
- )
- obj.extractall(path=targetdir)
- return targetdir
- WININST_PATTERN = r'([a-zA-Z0-9\-\_]*|[a-zA-Z\-\_\.]*)-([0-9\.\-]*[a-z]*[0-9]?)(-Qt-([0-9\.]+))?.(win32|win\-amd64)(-py([0-9\.]+))?(-setup)?\.exe'
- # SOURCE_PATTERN defines what an acceptable source package name is
- # As of 2014-09-08 :
- # - the wheel package format is accepte in source directory
- # - the tricky regexp is tuned also to support the odd jolib naming :
- # . joblib-0.8.3_r1-py2.py3-none-any.whl,
- # . joblib-0.8.3-r1.tar.gz
- 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)'
- # WHEELBIN_PATTERN defines what an acceptable binary wheel package is
- # "cp([0-9]*)" to replace per cp(34) for python3.4
- # "win32|win\_amd64" to replace per "win\_amd64" for 64bit
- WHEELBIN_PATTERN = r'([a-zA-Z0-9\-\_\.]*)-([0-9\.\_]*[a-z0-9\+]*[0-9]?)-cp([0-9]*)\-[0-9|c|o|n|e|p|m]*\-(win32|win\_amd64)\.whl'
- def get_source_package_infos(fname):
- """Return a tuple (name, version) of the Python source package"""
- if fname[-4:] == '.whl':
- return osp.basename(fname).split("-")[:2]
- match = re.match(SOURCE_PATTERN, osp.basename(fname))
- if match is not None:
- return match.groups()[:2]
- def build_wininst(
- root,
- python_exe=None,
- copy_to=None,
- architecture=None,
- verbose=False,
- installer='bdist_wininst',
- ):
- """Build wininst installer from Python package located in *root*
- and eventually copy it to *copy_to* folder.
- Return wininst installer full path."""
- if python_exe is None:
- python_exe = sys.executable
- assert osp.isfile(python_exe)
- cmd = [python_exe, 'setup.py', 'build']
- if architecture is not None:
- archstr = (
- 'win32' if architecture == 32 else 'win-amd64'
- )
- cmd += ['--plat-name=%s' % archstr]
- cmd += [installer]
- # root = a tmp dir in windows\tmp,
- if verbose:
- subprocess.call(cmd, cwd=root)
- else:
- p = subprocess.Popen(
- cmd,
- cwd=root,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- )
- p.communicate()
- p.stdout.close()
- p.stderr.close()
- distdir = osp.join(root, 'dist')
- if not osp.isdir(distdir):
- raise RuntimeError(
- "Build failed: see package README file for further"
- " details regarding installation requirements.\n\n"
- "For more concrete debugging infos, please try to build "
- "the package from the command line:\n"
- "1. Open a WinPython command prompt\n"
- "2. Change working directory to the appropriate folder\n"
- "3. Type `python setup.py build install`"
- )
- pattern = WININST_PATTERN.replace(
- r'(win32|win\-amd64)', archstr
- )
- for distname in os.listdir(distdir):
- match = re.match(pattern, distname)
- if match is not None:
- break
- # for wheels (winpython here)
- match = re.match(SOURCE_PATTERN, distname)
- if match is not None:
- break
- match = re.match(WHEELBIN_PATTERN, distname)
- if match is not None:
- break
- else:
- raise RuntimeError(
- "Build failed: not a pure Python package? %s"
- % distdir
- )
- src_fname = osp.join(distdir, distname)
- if copy_to is None:
- return src_fname
- else:
- dst_fname = osp.join(copy_to, distname)
- shutil.move(src_fname, dst_fname)
- if verbose:
- print(
- (
- "Move: %s --> %s"
- % (src_fname, (dst_fname))
- )
- )
- # remove tempo dir 'root' no more needed
- shutil.rmtree(root, onerror=onerror)
- return dst_fname
- def direct_pip_install(
- fname,
- python_exe=None,
- architecture=None,
- verbose=False,
- install_options=None,
- ):
- """Direct install via pip !"""
- copy_to = osp.dirname(fname)
- if python_exe is None:
- python_exe = sys.executable
- assert osp.isfile(python_exe)
- myroot = os.path.dirname(python_exe)
- cmd = [python_exe, '-m', 'pip', 'install']
- if install_options:
- cmd += install_options # typically ['--no-deps']
- print('pip install_options', install_options)
- cmd += [fname]
- if verbose:
- subprocess.call(cmd, cwd=myroot)
- else:
- p = subprocess.Popen(
- cmd,
- cwd=myroot,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- )
- stdout, stderr = p.communicate()
- the_log = "%s" % stdout + "\n %s" % stderr
- if (
- ' not find ' in the_log
- or ' not found ' in the_log
- ):
- print("Failed to Install: \n %s \n" % fname)
- print("msg: %s" % the_log)
- raise RuntimeError
- p.stdout.close()
- p.stderr.close()
- src_fname = fname
- if copy_to is None:
- return src_fname
- else:
- if verbose:
- print("Installed %s" % src_fname)
- return src_fname
- def do_script(
- this_script,
- python_exe=None,
- copy_to=None,
- architecture=None,
- verbose=False,
- install_options=None,
- ):
- """Execute a script (get-pip typically)"""
- if python_exe is None:
- python_exe = sys.executable
- myroot = os.path.dirname(python_exe)
- # cmd = [python_exe, myroot + r'\Scripts\pip-script.py', 'install']
- cmd = [python_exe]
- if install_options:
- cmd += install_options # typically ['--no-deps']
- print('script install_options', install_options)
- if this_script:
- cmd += [this_script]
- # print('build_wheel', myroot, cmd)
- print("Executing ", cmd)
- if verbose:
- subprocess.call(cmd, cwd=myroot)
- else:
- p = subprocess.Popen(
- cmd,
- cwd=myroot,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- )
- p.communicate()
- p.stdout.close()
- p.stderr.close()
- if verbose:
- print("Executed " % cmd)
- return 'ok'
- if __name__ == '__main__':
- print_box("Test")
- dname = sys.prefix
- print((dname + ':', '\n', get_python_infos(dname)))
- # dname = r'E:\winpython\sandbox\python-2.7.3'
- # print dname+':', '\n', get_python_infos(dname)
- tmpdir = r'D:\Tests\winpython_tests'
- if not osp.isdir(tmpdir):
- os.mkdir(tmpdir)
- print(
- (
- extract_archive(
- osp.join(
- r'D:\WinP\bd37',
- 'packages.win-amd64',
- 'python-3.7.3.amd64.zip',
- ),
- tmpdir,
- )
- )
- )
|