diff --git a/packages/packages/python/python.c b/packages/packages/python/python.c new file mode 100644 index 000000000..37b6504c5 --- /dev/null +++ b/packages/packages/python/python.c @@ -0,0 +1,222 @@ + + +#include "py4yap.h" +#include + +atom_t ATOM_true, ATOM_false, ATOM_colon, ATOM_dot, ATOM_none, ATOM_t, + ATOM_comma, ATOM_builtin, ATOM_A, ATOM_V, ATOM_self, ATOM_nil, ATOM_brackets, ATOM_curly_brackets; + +functor_t FUNCTOR_dollar1, FUNCTOR_abs1, FUNCTOR_all1, FUNCTOR_any1, + FUNCTOR_bin1, FUNCTOR_brackets1, FUNCTOR_comma2, FUNCTOR_dir1, + FUNCTOR_float1, FUNCTOR_int1, FUNCTOR_iter1, FUNCTOR_iter2, FUNCTOR_long1, + FUNCTOR_len1, FUNCTOR_curly1, FUNCTOR_ord1, FUNCTOR_range1, FUNCTOR_range2, + FUNCTOR_range3, FUNCTOR_sum1, FUNCTOR_pointer1, FUNCTOR_complex2, + FUNCTOR_plus2, FUNCTOR_sub2, FUNCTOR_mul2, FUNCTOR_div2, FUNCTOR_hat2, + FUNCTOR_colon2, FUNCTOR_comma2, FUNCTOR_equal2, FUNCTOR_sqbrackets2, + FUNCTOR_dot2, FUNCTOR_brackets1; + +X_API PyObject *py_Builtin; +X_API PyObject *py_Yapex; +X_API PyObject *py_Sys; +PyObject *py_Context; +PyObject *py_ModDict; + +VFS_t pystream; + +static void * +py_open( const char *name, const char *io_mode) { +#if HAVE_STRCASESTR + if (strcasestr(name,"//python/")== name) + name += strlen("//python/"); + #else + if (strstr(name,"//python/")== name) + name += strlen("//python/"); +#endif + // we assume object is already open, so there is no need to open it. + PyObject *stream = string_to_python( name, true, NULL); + if (stream == Py_None) + return NULL; + return stream; +} + +static bool +py_close(int sno) { + PyObject *s = YAP_foreign_stream(sno); + PyObject* fclose = PyObject_GetAttrString(s, "close"); + PyObject* rc= PyObject_CallObject(fclose, NULL); + bool v = (rc == Py_True); + return v; +} + +static PyObject * pyw; // buffer +static int pyw_kind; +PyObject * pyw_data; + +static int +py_put(int sno, int ch) { + PyObject *s = YAP_foreign_stream(sno); + PyUnicode_WRITE( pyw_kind, pyw_data, 0, ch ); + PyObject* fput = PyObject_GetAttrString(s, "write"); + PyObject_CallFunctionObjArgs(fput, pyw, NULL); + return ch; +} + +static int +py_get(int sno) { + PyObject *s = YAP_foreign_stream(sno); + PyObject* fget = PyObject_GetAttrString(s, "read"); + PyObject *pyr = PyObject_CallFunctionObjArgs(fget, PyLong_FromLong(1), NULL); + return PyUnicode_READ_CHAR( pyr, 0) ; +} + +static int64_t py_seek(int sno, int64_t where, int how) { + PyObject *s = YAP_foreign_stream(sno); + PyObject* fseek = PyObject_GetAttrString(s, "seek"); + PyObject *pyr = PyObject_CallFunctionObjArgs(fseek, PyLong_FromLong(where), PyLong_FromLong(how), NULL); + return PyLong_AsLong(pyr); +} + +static void +py_flush(int sno) { + PyObject *s = YAP_foreign_stream(sno); + PyObject* flush = PyObject_GetAttrString(s, "flush"); + PyObject_CallFunction( flush, NULL); +} + + + +static bool +init_python_stream(void) +{ + pyw = PyUnicode_FromString("x"); + pyw_kind = PyUnicode_KIND(pyw); + pyw_data = PyUnicode_DATA(pyw); + + pystream.name = "python stream"; + pystream.vflags = VFS_CAN_WRITE|VFS_CAN_EXEC| VFS_CAN_SEEK|VFS_HAS_PREFIX; + pystream.prefix = "//python/"; + pystream.suffix = NULL; + pystream.open = py_open; + pystream.close = py_close; + pystream.get_char = py_get; + pystream.put_char = py_put; + pystream.flush = py_flush; + pystream.seek = py_seek; + pystream.next = GLOBAL_VFS; + GLOBAL_VFS = &pystream; + // NULL; + return true; +} + +X_API PyObject *py_F2P; + +extern X_API bool python_in_python; + +static void add_modules(void) { + py_Main = PyImport_AddModule("__main__"); + Py_INCREF(py_Main); + py_Sys = PyImport_AddModule("sys"); + Py_INCREF(py_Sys); + py_Builtin = PyImport_AddModule("__builtin__"); + Py_INCREF(py_Builtin); + py_ModDict = PyObject_GetAttrString(py_Sys, "modules"); + // py_Yapex = PyImport_ImportModule("yap4py.yapi"); + // PyObject *py_Yap = + py_Yapex = PyImport_AddModule("yap4py.yapi"); + if (py_Yapex) + Py_INCREF(py_Yapex); + //py_F2P = PyObject_GetAttrString(py_Yap, "globals"); + py_F2P = NULL; + init_python_stream(); +} + + +static void install_py_constants(void) { + FUNCTOR_dot2 = PL_new_functor(PL_new_atom("."), 2); + // FUNCTOR_equal2 = PL_new_functor(PL_new_atom("="), 2); + // FUNCTOR_boolop1 = PL_new_functor(PL_new_atom("@"), 1); + ATOM_A = PL_new_atom("A"); + ATOM_V = PL_new_atom("V"); + ATOM_builtin = PL_new_atom("__builtin__"); + ATOM_comma = PL_new_atom(","); + ATOM_colon = PL_new_atom(":"); + ATOM_true = PL_new_atom("true"); + ATOM_false = PL_new_atom("false"); + ATOM_dot = PL_new_atom("."); + ATOM_self = PL_new_atom("self"); + ATOM_nil = PL_new_atom("[]"); + ATOM_brackets = PL_new_atom("()"); + ATOM_curly_brackets = PL_new_atom("{}"); + FUNCTOR_abs1 = PL_new_functor(PL_new_atom("abs"), 1); + FUNCTOR_all1 = PL_new_functor(PL_new_atom("all"), 1); + FUNCTOR_any1 = PL_new_functor(PL_new_atom("any"), 1); + FUNCTOR_bin1 = PL_new_functor(PL_new_atom("bin"), 1); + FUNCTOR_ord1 = PL_new_functor(PL_new_atom("ord"), 1); + FUNCTOR_int1 = PL_new_functor(PL_new_atom("int"), 1); + FUNCTOR_long1 = PL_new_functor(PL_new_atom("long"), 1); + FUNCTOR_float1 = PL_new_functor(PL_new_atom("float"), 1); + FUNCTOR_curly1 = PL_new_functor(PL_new_atom("{}"), 1); + FUNCTOR_brackets1 = PL_new_functor(PL_new_atom("()"), 1); + FUNCTOR_dollar1 = PL_new_functor(PL_new_atom("$"), 1); + FUNCTOR_pointer1 = PL_new_functor(PL_new_atom("__obj__"), 1); + FUNCTOR_dir1 = PL_new_functor(PL_new_atom("dir"), 1); + FUNCTOR_iter1 = PL_new_functor(PL_new_atom("iter"), 1); + FUNCTOR_iter2 = PL_new_functor(PL_new_atom("iter"), 2); + FUNCTOR_len1 = PL_new_functor(PL_new_atom("len"), 1); + FUNCTOR_range1 = PL_new_functor(PL_new_atom("range"), 1); + FUNCTOR_range2 = PL_new_functor(PL_new_atom("range"), 2); + FUNCTOR_range3 = PL_new_functor(PL_new_atom("range"), 3); + FUNCTOR_sum1 = PL_new_functor(PL_new_atom("sum"), 1); + FUNCTOR_complex2 = PL_new_functor(PL_new_atom("i"), 2); + FUNCTOR_plus2 = PL_new_functor(PL_new_atom("+"), 2); + FUNCTOR_sub2 = PL_new_functor(PL_new_atom("-"), 2); + FUNCTOR_mul2 = PL_new_functor(PL_new_atom("*"), 2); + FUNCTOR_div2 = PL_new_functor(PL_new_atom("/"), 2); + FUNCTOR_hat2 = PL_new_functor(PL_new_atom("^"), 2); + FUNCTOR_colon2 = PL_new_functor(PL_new_atom(":"), 2); + FUNCTOR_comma2 = PL_new_functor(PL_new_atom(","), 2); + FUNCTOR_equal2 = PL_new_functor(PL_new_atom("="), 2); + FUNCTOR_sqbrackets2 = PL_new_functor(PL_new_atom("[]"), 2); + } + +foreign_t end_python(void) { + if (!python_in_python) + Py_Finalize(); + + return true; +} + +static bool libpython_initialized = 0; + +X_API bool do_init_python(void) { + // char **argv; + if (libpython_initialized) + return true; + libpython_initialized = true; + + // PyGILState_STATE gstate = PyGILState_Ensure(); + term_t t = PL_new_term_ref(); + if (!python_in_python) + Py_Initialize(); + install_py_constants(); + PL_reset_term_refs(t); + install_pl2pl(); + // PyGILState_Release(gstate); + add_modules(); + return true; + +} + +#ifndef _WIN32 + + +O_API bool init_python_dll(void); + + +O_API bool init_python_dll(void) { + do_init_python(); + install_pypreds(); + return 1; +} + +#endif diff --git a/packages/python/swig/CMakeLists.txt b/packages/python/swig/CMakeLists.txt index 6bc4ae91b..a4abea4f0 100644 --- a/packages/python/swig/CMakeLists.txt +++ b/packages/python/swig/CMakeLists.txt @@ -5,7 +5,7 @@ include(FindPythonModule) -set (PROLOG_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/yapi.yap ${CMAKE_CURRENT_SOURCE_DIR}/jupyter.yap) +set (PROLOG_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/yapi.yap) set (PYTHON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/yapi.py ${CMAKE_CURRENT_SOURCE_DIR}/__init__.py ${CMAKE_CURRENT_SOURCE_DIR}/__main__.py) file(RELATIVE_PATH RELATIVE_SOURCE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}) @@ -76,17 +76,15 @@ add_custom_target( YAP4PY_SETUP_DIRS ) add_custom_target( YAP4PY ALL - COMMAND ${PYTHON_EXECUTABLE} -m pip uninstall -y YAP4PY COMMAND ${SWIG_EXECUTABLE} -python -modern -c++ -py3 -DX_API -I${CMAKE_SOURCE_DIR}/CXX -I${CMAKE_SOURCE_DIR}/include -I${CMAKE_SOURCE_DIR}/H -I${CMAKE_SOURCE_DIR}/H/generated -I${CMAKE_SOURCE_DIR}/OPTYap -I../../.. -o yap_wrap.cpp yap.i COMMAND ${PYTHON_EXECUTABLE} setup.py sdist bdist_wheel WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} DEPENDS YAP4PY_SETUP) - install(CODE "execute_process( - COMMAND ${PYTHON_EXECUTABLE} -m pip install --force --no-index -f packages/python/swig/dist YAP4PY - WORKING_DIRECTORY ${CMAKE_BINARY_DIR})" + COMMAND ${PYTHON_EXECUTABLE} -m pip install --ignore-installed ${CMAKE_CURRENT_BINARY_DIR} + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})" DEPENDS Py4YAP ${CMAKE_BINARY_DIR}/${YAP_STARTUP} ${dlls} ) install(FILES ${PROLOG_SOURCES} DESTINATION ${libpl}) diff --git a/packages/python/swig/__main__.py b/packages/python/swig/__main__.py index 7ba19d1a8..560b16d09 100644 --- a/packages/python/swig/__main__.py +++ b/packages/python/swig/__main__.py @@ -4,11 +4,7 @@ import sys import yapi -def main(args=None): - """The main routine.""" - if args is None: - args = sys.argv[1:] - yap.yapi.live(args) - -if __name__ == "__main__": - main() +"""The main routine.""" +if args is None: + args = sys.argv[1:] + yap4pi.yapi.live(args) diff --git a/packages/python/yap_kernel/yap_ipython/core/oinspect.py b/packages/python/yap_kernel/yap_ipython/core/oinspect.py new file mode 100644 index 000000000..c65dd28cc --- /dev/null +++ b/packages/python/yap_kernel/yap_ipython/core/oinspect.py @@ -0,0 +1,100 @@ +from IPython.core.oinspect import * + + +from pygments import highlight +from pygments.lexers import PrologLexer +from pygments.formatters import HtmlFormatter + + +def yaplight(code): + return highlight(code, PythonLexer(), HtmlFormatter(noclasses=True)) + +def _get_info(self, obj, oname='', formatter=None, info=None, detail_level=0): + """Retrieve an info dict and format it. + + Parameters + ========== + + obj: any + Object to inspect and return info from + oname: str (default: ''): + Name of the variable pointing to `obj`. + formatter: callable + info: + already computed informations + detail_level: integer + Granularity of detail level, if set to 1, give more informations. + """ + + info = self._info(obj, oname=oname, info=info, detail_level=detail_level) + + _mime = { + 'text/plain': [], + 'text/html': '', + } + + def append_field(bundle, title, key, formatter=None): + field = info[key] + if field is not None: + formatted_field = self._mime_format(field, formatter) + bundle['text/plain'].append((title, formatted_field['text/plain'])) + bundle['text/html'] += '

' + title + '

\n' + formatted_field['text/html'] + '\n' + + def code_formatter(text): + return { + 'text/plain': self.format(text), + 'text/html': yaplight(text) + } + + if info['isalias']: + append_field(_mime, 'Repr', 'string_form') + + elif info['ismagic']: + if detail_level > 0: + append_field(_mime, 'Source', 'source', code_formatter) + else: + append_field(_mime, 'Docstring', 'docstring', formatter) + append_field(_mime, 'File', 'file') + + # elif info['isclass'] or is_simple_callable(obj): + # # Functions, methods, classes + # append_field(_mime, 'Signature', 'definition', code_formatter) + # append_field(_mime, 'Init signature', 'init_definition', code_formatter) + # if detail_level > 0 and info['source']: + # append_field(_mime, 'Source', 'source', code_formatter) + # else: + # append_field(_mime, 'Docstring', 'docstring', formatter) + # append_field(_mime, 'Init docstring', 'init_docstring', formatter) + # + # append_field(_mime, 'File', 'file') + # append_field(_mime, 'Type', 'type_name') + + else: + # General Python objects + append_field(_mime, 'Signature', 'definition', code_formatter) + append_field(_mime, 'Call signature', 'call_def', code_formatter) + append_field(_mime, 'Type', 'type_name') + append_field(_mime, 'String form', 'string_form') + + # Namespace + if info['namespace'] != 'Interactive': + append_field(_mime, 'Namespace', 'namespace') + + append_field(_mime, 'Length', 'length') + append_field(_mime, 'File', 'file') + + # Source or docstring, depending on detail level and whether + # source found. + # if detail_level > 0 and info['source']: + append_field(_mime, 'Source', 'source', code_formatter) + # else: + # append_field(_mime, 'Docstring', 'docstring', formatter) + + append_field(_mime, 'Class docstring', 'class_docstring', formatter) + append_field(_mime, 'Init docstring', 'init_docstring', formatter) + append_field(_mime, 'Call docstring', 'call_docstring', formatter) + + + return self.format_mime(_mime) + +Inspector._get_info = _get_info diff --git a/packages/python/yap_kernel/yap_ipython/display.py b/packages/python/yap_kernel/yap_ipython/display.py new file mode 100644 index 000000000..7d248ba02 --- /dev/null +++ b/packages/python/yap_kernel/yap_ipython/display.py @@ -0,0 +1,16 @@ +"""Public API for display tools in IPython. +""" + +#----------------------------------------------------------------------------- +# Copyright (C) 2012 The IPython Development Team +# +# Distributed under the terms of the BSD License. The full license is in +# the file COPYING, distributed as part of this software. +#----------------------------------------------------------------------------- + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + +from IPython.core.display import * +from IPython.lib.display import * diff --git a/packages/python/yap_kernel/yap_ipython/shellapp.py b/packages/python/yap_kernel/yap_ipython/shellapp.py new file mode 100644 index 000000000..9902c7bf8 --- /dev/null +++ b/packages/python/yap_kernel/yap_ipython/shellapp.py @@ -0,0 +1,408 @@ +# encoding: utf-8 +""" +A mixin for :class:`~IPython.core.application.Application` classes that +launch InteractiveShell instances, load extensions, etc. +""" + +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. + +import glob +from itertools import chain +import os +import sys + +from traitlets.config.application import boolean_flag +from traitlets.config.configurable import Configurable +from traitlets.config.loader import Config +from IPython.core.application import SYSTEM_CONFIG_DIRS, ENV_CONFIG_DIRS +from IPython.core import pylabtools +from IPython.utils.contexts import preserve_keys +from IPython.utils.path import filefind +from traitlets import ( + Unicode, Instance, List, Bool, CaselessStrEnum, observe, +) +from IPython.terminal import pt_inputhooks + +#----------------------------------------------------------------------------- +# Aliases and Flags +#----------------------------------------------------------------------------- + +gui_keys = tuple(sorted(pt_inputhooks.backends) + sorted(pt_inputhooks.aliases)) + +backend_keys = sorted(pylabtools.backends.keys()) +backend_keys.insert(0, 'auto') + +shell_flags = {} + +addflag = lambda *args: shell_flags.update(boolean_flag(*args)) +addflag('autoindent', 'YAPInteractive.autoindent', + 'Turn on autoindenting.', 'Turn off autoindenting.' +) +addflag('automagic', 'YAPInteractive.automagic', + """Turn on the auto calling of magic commands. Type %%magic at the + IPython prompt for more information.""", + 'Turn off the auto calling of magic commands.' +) +addflag('pdb', 'YAPInteractive.pdb', + "Enable auto calling the pdb debugger after every exception.", + "Disable auto calling the pdb debugger after every exception." +) +addflag('pprint', 'PlainTextFormatter.pprint', + "Enable auto pretty printing of results.", + "Disable auto pretty printing of results." +) +addflag('color-info', 'YAPInteractive.color_info', + """IPython can display information about objects via a set of functions, + and optionally can use colors for this, syntax highlighting + source code and various other elements. This is on by default, but can cause + problems with some pagers. If you see such problems, you can disable the + colours.""", + "Disable using colors for info related things." +) +nosep_config = Config() +nosep_config.YAPInteractive.separate_in = '' +nosep_config.YAPInteractive.separate_out = '' +nosep_config.YAPInteractive.separate_out2 = '' + +shell_flags['nosep']=(nosep_config, "Eliminate all spacing between prompts.") +shell_flags['pylab'] = ( + {'YAPInteractiveApp' : {'pylab' : 'auto'}}, + """Pre-load matplotlib and numpy for interactive use with + the default matplotlib backend.""" +) +shell_flags['matplotlib'] = ( + {'YAPInteractiveApp' : {'matplotlib' : 'auto'}}, + """Configure matplotlib for interactive use with + the default matplotlib backend.""" +) + +# it's possible we don't want short aliases for *all* of these: +shell_aliases = dict( + autocall='YAPInteractive.autocall', + colors='YAPInteractive.colors', + logfile='YAPInteractive.logfile', + logappend='YAPInteractive.logappend', + c='YAPInteractiveApp.code_to_run', + m='YAPInteractiveApp.module_to_run', + ext='YAPInteractiveApp.extra_extension', + gui='YAPInteractiveApp.gui', + pylab='YAPInteractiveApp.pylab', + matplotlib='YAPInteractiveApp.matplotlib', +) +shell_aliases['cache-size'] = 'YAPInteractive.cache_size' + +#----------------------------------------------------------------------------- +# Main classes and functions +#----------------------------------------------------------------------------- + +class YAPInteractiveApp(Configurable): + """A Mixin for applications that start YAPInteractive instances. + + Provides configurables for loading extensions and executing files + as part of configuring a Shell environment. + + The following methods should be called by the :meth:`initialize` method + of the subclass: + + - :meth:`init_path` + - :meth:`init_shell` (to be implemented by the subclass) + - :meth:`init_gui_pylab` + - :meth:`init_extensions` + - :meth:`init_code` + """ + extensions = List(Unicode(), + help="A list of dotted module names of IPython extensions to load." + ).tag(config=True) + extra_extension = Unicode('', + help="dotted module name of an IPython extension to load." + ).tag(config=True) + + reraise_ipython_extension_failures = Bool(False, + help="Reraise exceptions encountered loading IPython extensions?", + ).tag(config=True) + + # Extensions that are always loaded (not configurable) + default_extensions = List(Unicode(), [u'storemagic']).tag(config=False) + + hide_initial_ns = Bool(True, + help="""Should variables loaded at startup (by startup files, exec_lines, etc.) + be hidden from tools like %who?""" + ).tag(config=True) + + exec_files = List(Unicode(), + help="""List of files to run at IPython startup.""" + ).tag(config=True) + exec_PYTHONSTARTUP = Bool(True, + help="""Run the file referenced by the PYTHONSTARTUP environment + variable at IPython startup.""" + ).tag(config=True) + file_to_run = Unicode('', + help="""A file to be run""").tag(config=True) + + exec_lines = List(Unicode(), + help="""lines of code to run at IPython startup.""" + ).tag(config=True) + code_to_run = Unicode('', + help="Execute the given command string." + ).tag(config=True) + module_to_run = Unicode('', + help="Run the module as a script." + ).tag(config=True) + gui = CaselessStrEnum(gui_keys, allow_none=True, + help="Enable GUI event loop integration with any of {0}.".format(gui_keys) + ).tag(config=True) + matplotlib = CaselessStrEnum(backend_keys, allow_none=True, + help="""Configure matplotlib for interactive use with + the default matplotlib backend.""" + ).tag(config=True) + pylab = CaselessStrEnum(backend_keys, allow_none=True, + help="""Pre-load matplotlib and numpy for interactive use, + selecting a particular matplotlib backend and loop integration. + """ + ).tag(config=True) + pylab_import_all = Bool(True, + help="""If true, IPython will populate the user namespace with numpy, pylab, etc. + and an ``import *`` is done from numpy and pylab, when using pylab mode. + + When False, pylab mode should not import any names into the user namespace. + """ + ).tag(config=True) + shell = Instance('yap_ipython.core.interactiveshell.YAPInteractiveABC', + allow_none=True) + # whether interact-loop should start + interact = Bool(True) + + user_ns = Instance(dict, args=None, allow_none=True) + @observe('user_ns') + def _user_ns_changed(self, change): + if self.shell is not None: + self.shell.user_ns = change['new'] + self.shell.init_user_ns() + + def init_path(self): + """Add current working directory, '', to sys.path""" + if sys.path[0] != '': + sys.path.insert(0, '') + + def init_shell(self): + raise NotImplementedError("Override in subclasses") + + def init_gui_pylab(self): + """Enable GUI event loop integration, taking pylab into account.""" + enable = False + shell = self.shell + if self.pylab: + enable = lambda key: shell.enable_pylab(key, import_all=self.pylab_import_all) + key = self.pylab + elif self.matplotlib: + enable = shell.enable_matplotlib + key = self.matplotlib + elif self.gui: + enable = shell.enable_gui + key = self.gui + + if not enable: + return + + try: + r = enable(key) + except ImportError: + self.log.warning("Eventloop or matplotlib integration failed. Is matplotlib installed?") + self.shell.showtraceback() + return + except Exception: + self.log.warning("GUI event loop or pylab initialization failed") + self.shell.showtraceback() + return + + if isinstance(r, tuple): + gui, backend = r[:2] + self.log.info("Enabling GUI event loop integration, " + "eventloop=%s, matplotlib=%s", gui, backend) + if key == "auto": + print("Using matplotlib backend: %s" % backend) + else: + gui = r + self.log.info("Enabling GUI event loop integration, " + "eventloop=%s", gui) + + def init_extensions(self): + """Load all IPython extensions in IPythonApp.extensions. + + This uses the :meth:`ExtensionManager.load_extensions` to load all + the extensions listed in ``self.extensions``. + """ + try: + self.log.debug("Loading IPython extensions...") + extensions = self.default_extensions + self.extensions + if self.extra_extension: + extensions.append(self.extra_extension) + for ext in extensions: + try: + self.log.info("Loading IPython extension: %s" % ext) + self.shell.extension_manager.load_extension(ext) + except: + if self.reraise_ipython_extension_failures: + raise + msg = ("Error in loading extension: {ext}\n" + "Check your config files in {location}".format( + ext=ext, + location=self.profile_dir.location + )) + self.log.warning(msg, exc_info=True) + except: + if self.reraise_ipython_extension_failures: + raise + self.log.warning("Unknown error in loading extensions:", exc_info=True) + + def init_code(self): + """run the pre-flight code, specified via exec_lines""" + self._run_startup_files() + self._run_exec_lines() + self._run_exec_files() + + # Hide variables defined here from %who etc. + if self.hide_initial_ns: + self.shell.user_ns_hidden.update(self.shell.user_ns) + + # command-line execution (ipython -i script.py, ipython -m module) + # should *not* be excluded from %whos + self._run_cmd_line_code() + self._run_module() + + # flush output, so itwon't be attached to the first cell + sys.stdout.flush() + sys.stderr.flush() + + def _run_exec_lines(self): + """Run lines of code in IPythonApp.exec_lines in the user's namespace.""" + if not self.exec_lines: + return + try: + self.log.debug("Running code from IPythonApp.exec_lines...") + for line in self.exec_lines: + try: + self.log.info("Running code in user namespace: %s" % + line) + self.shell.run_cell(line, store_history=False) + except: + self.log.warning("Error in executing line in user " + "namespace: %s" % line) + self.shell.showtraceback() + except: + self.log.warning("Unknown error in handling IPythonApp.exec_lines:") + self.shell.showtraceback() + + def _exec_file(self, fname, shell_futures=False): + try: + full_filename = filefind(fname, [u'.', self.ipython_dir]) + except IOError: + self.log.warning("File not found: %r"%fname) + return + # Make sure that the running script gets a proper sys.argv as if it + # were run from a system shell. + save_argv = sys.argv + sys.argv = [full_filename] + self.extra_args[1:] + try: + if os.path.isfile(full_filename): + self.log.info("Running file in user namespace: %s" % + full_filename) + # Ensure that __file__ is always defined to match Python + # behavior. + with preserve_keys(self.shell.user_ns, '__file__'): + self.shell.user_ns['__file__'] = fname + if full_filename.endswith('.ipy'): + self.shell.safe_execfile_ipy(full_filename, + shell_futures=shell_futures) + else: + # default to python, even without extension + self.shell.safe_execfile(full_filename, + self.shell.user_ns, + shell_futures=shell_futures, + raise_exceptions=True) + finally: + sys.argv = save_argv + + def _run_startup_files(self): + """Run files from profile startup directory""" + startup_dirs = [self.profile_dir.startup_dir] + [ + os.path.join(p, 'startup') for p in chain(ENV_CONFIG_DIRS, SYSTEM_CONFIG_DIRS) + ] + startup_files = [] + + if self.exec_PYTHONSTARTUP and os.environ.get('PYTHONSTARTUP', False) and \ + not (self.file_to_run or self.code_to_run or self.module_to_run): + python_startup = os.environ['PYTHONSTARTUP'] + self.log.debug("Running PYTHONSTARTUP file %s...", python_startup) + try: + self._exec_file(python_startup) + except: + self.log.warning("Unknown error in handling PYTHONSTARTUP file %s:", python_startup) + self.shell.showtraceback() + for startup_dir in startup_dirs[::-1]: + startup_files += glob.glob(os.path.join(startup_dir, '*.py')) + startup_files += glob.glob(os.path.join(startup_dir, '*.ipy')) + if not startup_files: + return + + self.log.debug("Running startup files from %s...", startup_dir) + try: + for fname in sorted(startup_files): + self._exec_file(fname) + except: + self.log.warning("Unknown error in handling startup files:") + self.shell.showtraceback() + + def _run_exec_files(self): + """Run files from IPythonApp.exec_files""" + if not self.exec_files: + return + + self.log.debug("Running files in IPythonApp.exec_files...") + try: + for fname in self.exec_files: + self._exec_file(fname) + except: + self.log.warning("Unknown error in handling IPythonApp.exec_files:") + self.shell.showtraceback() + + def _run_cmd_line_code(self): + """Run code or file specified at the command-line""" + if self.code_to_run: + line = self.code_to_run + try: + self.log.info("Running code given at command line (c=): %s" % + line) + self.shell.run_cell(line, store_history=False) + except: + self.log.warning("Error in executing line in user namespace: %s" % + line) + self.shell.showtraceback() + if not self.interact: + self.exit(1) + + # Like Python itself, ignore the second if the first of these is present + elif self.file_to_run: + fname = self.file_to_run + if os.path.isdir(fname): + fname = os.path.join(fname, "__main__.py") + try: + self._exec_file(fname, shell_futures=True) + except: + self.shell.showtraceback(tb_offset=4) + if not self.interact: + self.exit(1) + + def _run_module(self): + """Run module specified at the command-line.""" + if self.module_to_run: + # Make sure that the module gets a proper sys.argv as if it were + # run using `python -m`. + save_argv = sys.argv + sys.argv = [sys.executable] + self.extra_args + try: + self.shell.safe_run_module(self.module_to_run, + self.shell.user_ns) + finally: + sys.argv = save_argv