Source code for pymyinstall.win_installer.win_setup_main_checkings

# -*- coding: utf-8 -*-
"""
Run some checkings about the distribution

.. versionadded:: 1.1


:githublink:`%|py|8`
"""
from __future__ import print_function

import os
import sys

from .win_exception import WinInstallDistributionError
from ..packaged.automate_install import find_module_install
from ..installhelper.install_venv_helper import run_cmd_path
from ..packaged import small_set
from ..installhelper.module_install import ModuleInstall, run_cmd

if sys.version_info[0] == 2:
    FileNotFoundError = Exception


[docs]def distribution_checkings(python_path, tools_path, fLOG=print, skip_import=False, module_list=None): """ checks a distribution was properly executed :param python_path: path for python :param tools_path: path for tools :param fLOG: logging function :param skip_import: skip the validation of every installed module (for unit test purposes) :param module_list: module list to check The function raises :class:`WinInstallDistributionError <pymyinstall.win_installer.win_exception.WinInstallDistributionError>` if an issue is detected. If *python_path* is None, it is replace by ``os.path.dirname(sys.executable)``. .. versionadded:: 1.1 :githublink:`%|py|38` """ exceptions = [] files_to_check = ["jupyter-console.exe", "jupyter-qtconsole.exe", "jupyter-notebook.exe", "jupyter.exe"] if python_path is None: python_path = os.path.dirname(sys.executable) # on Python 3.5, pip does not always exist # in a virtual environment (probable bug) pip = os.path.join(python_path, "pip.exe") pep8 = os.path.join(python_path, "pep8.exe") if not os.path.exists(pip) and not os.path.exists(pep8): scripts = os.path.join(python_path, "Scripts") files_to_check.extend( [("spyder.bat", 'spyder.exe'), "autopep8.exe"]) if sys.version_info[:2] != (3, 5): files_to_check.append("pip.exe") else: scripts = python_path ###################################### # check Jupyter, numpy, works properly ###################################### if sys.platform.startswith("win"): new_files_to_check = [] for file in files_to_check: if isinstance(file, tuple): fs = [os.path.join(scripts, f) for f in file] ft = [f for f in fs if os.path.exists(f)] if len(ft) > 0: new_files_to_check.append(os.path.split(ft[0])[-1]) else: try: raise FileNotFoundError(fs) except Exception as e: exceptions.append(e) else: f = os.path.join(scripts, file) if not os.path.exists(f): try: raise FileNotFoundError(f) except Exception as e: exceptions.append(e) else: new_files_to_check.append(file) files_to_check = new_files_to_check ################################ # check that module can be imported ################################ if not skip_import: res = import_every_module( python_path, module_list, only_installed=True, fLOG=fLOG) mes = [] for r in res: if not r[0]: m = "------\nFAILED {0}\nOUT\n{1}\nERR--E\n{2}".format( r[1].name, r[2], r[3]) mes.append(m) if len(mes) > 0: raise WinInstallDistributionError( "cannot import modules\n" + "\n".join(mes)) ######## # final ######## if len(exceptions) > 0: typstr = str # unicode# errors = "\n----\n".join("{0}\n{1}".format(type(_), typstr(_)) for _ in exceptions) raise WinInstallDistributionError("\n" + errors)
[docs]def import_every_module(python_path, module_list, only_installed=True, fLOG=print, start=0, end=-1): """ import every module in *module_list* assuming they are defined by :class:`ModuleInstall <pymyinstall.installhelper.module_install.ModuleInstall>` or a string :param python_path: python path :param module_list: module list, if None, consider the largest list :param only_installed: True to check only installed module in the list, False to test them without checking they were installed :param start: start the list at *start* :param end: end the list at *end* or -1 for all :return: list of tuple (success, failing modules, output, error) :githublink:`%|py|123` """ if python_path is None: python_path = os.path.dirname(sys.executable) if os.path.isfile(python_path): python_path = os.path.dirname(python_path) if module_list is None: module_list = small_set() def tomod(m): if isinstance(m, ModuleInstall): return m else: return find_module_install(m) module_list = [tomod(m) for m in module_list] def noLOG(*l, **p): pass def is_errored_line(line): if ".py" in line: if "UserWarning:" in line: return False if "FutureWarning:" in line: return False return True return False def analyze_error_success(mod, err): if err is None or len(err) == 0: return True if "ImportError" in err: return False if "ShimWarning" in err: return True if "kivy" in mod.name.lower(): if "error" not in err.lower(): return True if err is not None: lines = err.split("\n") for line in lines: if ".py" in line: res = is_errored_line(lines) if res: return False else: continue return True return False res = [] for i, m in enumerate(module_list): if i < start: continue if end != -1 and i >= end: fLOG("[pymy] {0}/{1}: end".format(i, len(module_list) - start)) break if m.is_installed_version(): if m.name in ["libpython", "tutormagic", "pymyinstall", "distribute"]: # nothing to import or failure fLOG("[pymy] {0}/{1}: skipped".format(i, len(module_list) - start), m) continue elif m.mname == "theano": # we need to check that TDM-GCC is installed cmd = "g++ --help" out, err = run_cmd(cmd, wait=True, fLOG=fLOG) if err is not None and len(err) > 0: fLOG("[pymy] {0}/{1}: failed (g++)".format(i, len(module_list) - start), m) res.append((False, m, out, err)) continue if "Usage: g++ [options] file..." not in out: fLOG("[pymy] {0}/{1}: failed (g++)".format(i, len(module_list) - start), m) res.append((False, m, out, err)) continue sc = "import " + m.ImportName if m.name == "cvxopt": # see # http://stackoverflow.com/questions/14778178/import-cvxopt-base-the-specified-module-could-not-be-found sc += "import numpy;" + sc if m.name == "scipy": # see # http://stackoverflow.com/questions/14778178/import-cvxopt-base-the-specified-module-could-not-be-found sc += sc + ";import scipy.stats" out, err = run_cmd_path( python_path, sc, fLOG=fLOG, communicate=True, timeout=40) suc = analyze_error_success(m, err) nextm = module_list[i + 1] if i + 1 < len(module_list) else "" if suc: fLOG("[pymy] {0}/{1}: success".format(i, len(module_list) - start), m, "-->", nextm) else: fLOG("[pymy] {0}/{1}: failed ".format(i, len(module_list) - start), m, "-->", nextm) if m.name == "paramiko": err = "You might have to install manually pycrypto.\n" + \ "Please read http://www.xavierdupre.fr/app/pymyinstall/helpsphinx//blog/2016/2016-02-27_pycrypto_paramiko.html" + \ err err = [(" - ERR--F: " if is_errored_line(line) else " - OK: ") + line.rstrip("\n\r") for line in err.split("\n")] err = "\n".join(err) res.append((suc, m, out, err)) return res