Source code for pyquickhelper.pycode.call_setup_hook

"""
Helper for the setup.


:githublink:`%|py|5`
"""
import os
import sys
import shlex
import subprocess
from ..loghelper import noLOG, run_cmd
from ..loghelper.run_cmd import get_interpreter_path
from .open_script_file import open_script


[docs]def call_setup_hook_cmd(folder, module_name, function_name="_setup_hook", additional_paths=None, interpreter_path=None, check=True, **args): """ Prepares the command line to call function :func:`_setup_hook <pyquickhelper._setup_hook>` for a specific module. :param folder: folder which contains the setup :param module_name: module name :param function_name: function to call by default :param additional_paths: additional_paths to add to *sys.path* before call the function :param args: additional parameter (dictionary) :param interpreter_path: to use a different interpreter than the current one :param check: check existence of filename :return: stdout, stderr The function expects to find file ``__init__.py`` in ``<folder>/src/<module_name>``. .. versionadded:: 1.9 Parameter *check* was added. :githublink:`%|py|35` """ this = os.path.abspath(os.path.dirname(__file__)) this = os.path.normpath(os.path.join(this, "..", "..")) src = os.path.abspath(os.path.join(folder, "src")) if check and not os.path.exists(src): src = os.path.abspath(folder) if check and not os.path.exists(src): raise FileNotFoundError( # pragma: no cover "Unable to find folder '{}'.".format(folder)) if additional_paths is None: additional_paths = [src, this] else: additional_paths = [src, this] + additional_paths if args is None or len(args) == 0: str_args = "" else: typstr = str str_args = "**" + typstr(args) code = ["import sys", ] code.extend(["sys.path.append('{0}')".format( d.replace("\\", "/")) for d in additional_paths]) code.extend(["from {0} import {1}".format(module_name, function_name), "{0}({1})".format(function_name, str_args), "sys.exit(0)"]) code = ";".join(code) if interpreter_path is None: interpreter_path = get_interpreter_path() cmd = [interpreter_path, "-c", '"{0}"'.format(code)] cmd = " ".join(cmd) return cmd, code
[docs]def call_setup_hook(folder, module_name, fLOG=noLOG, must_be=False, function_name="_setup_hook", use_print=False, force_call=False, additional_paths=None, **args): """ Calls function :func:`_setup_hook <pyquickhelper._setup_hook>` for a specific module, it is called in a separate process. :param folder: folder which contains the setup :param module_name: module name :param fLOG: logging function :param must_be: raises an exception if :func:`_setup_hook <pyquickhelper._setup_hook>` is not found :param function_name: function to call by default :param use_print: use print to display information :param force_call: use *subprocess.call* instead of :func:`run_cmd <pyquickhelper.loghelper.run_cmd.run_cmd>` :param additional_paths: additional_paths to add to *sys.path* before call the function :param args: additional parameter (dictionary) :return: stdout, stderr The function expects to find file ``__init__.py`` in ``<folder>/src/<module_name>``. :githublink:`%|py|92` """ cmd, code = call_setup_hook_cmd(folder=folder, module_name=module_name, function_name=function_name, additional_paths=additional_paths, **args) if use_print: # pragma: no cover print("CODE:\n", code) print("CMD:\n", cmd) fLOG("[call_setup_hook] calls _setup_hook from", module_name) if not force_call and sys.platform.startswith("win"): out, err = run_cmd( # pragma: no cover cmd, wait=True, fLOG=fLOG, log_error=False) exit = 0 # pragma: no cover else: if use_print: # pragma: no cover print("subprocess.call", cmd) if not sys.platform.startswith("win"): args = shlex.split(cmd) else: args = cmd # pragma: no cover exit = subprocess.call(args) out = "linux" err = "" if exit != 0: src = os.path.abspath(os.path.join(folder, "src")) if not os.path.exists(src): # pragma: no cover src = os.path.abspath(folder) if not os.path.exists(src): raise FileNotFoundError( # pragma: no cover "Unable to find folder '{}'.".format(folder)) init = os.path.join(src, module_name, "__init__.py") with open_script(init, "r") as f: content = f.read() sdef = 'def {0}'.format(function_name) if sdef not in content: exit = 0 err = "ImportError: cannot import name '{0}'".format( function_name) fLOG("[call_setup_hook] end of call _setup_hook") if use_print: # pragma: no cover print("OUT:\n", out) if err: if "cannot import name '_setup_hook'" in err: fLOG("[call_setup_hook] _setup_hook was not found.") else: print("[pyqerror]\n", err) def error(): mes = ("**CMD:\n{3}\n**CODE:\n{0}\n**OUT:\n{1}\n**[pyqerror]" "\n{2}\nexit={4}").format( # pragma: no cover code.replace(";", "\n"), out, err, cmd, exit) return mes # pragma: no cover if not must_be and ( "ImportError: cannot import name '{0}'".format(function_name) in err or "ImportError: cannot import name {0}".format(function_name) in err): # no _setup_hook return out, "no {0}".format(function_name) if "Error while finding spec " in err: raise Exception(error()) # pragma: no cover if "ImportError: No module named" in err: raise Exception(error()) # pragma: no cover if exit != 0: raise Exception(error()) # pragma: no cover out = "CMD: {0}\n---\n{1}".format(cmd, out) return out, err