Example #1
0
class IPythonApp(Application):
    name = 'ipython'
    config_file_name = _default_config_file_name

    def create_default_config(self):
        super(IPythonApp, self).create_default_config()
        self.default_config.Global.display_banner = True
        
        # If the -c flag is given or a file is given to run at the cmd line
        # like "ipython foo.py", normally we exit without starting the main
        # loop.  The force_interact config variable allows a user to override
        # this and interact.  It is also set by the -i cmd line flag, just
        # like Python.
        self.default_config.Global.force_interact = False

        # By default always interact by starting the IPython mainloop.
        self.default_config.Global.interact = True

        # Let the parent class set the default, but each time log_level
        # changes from config, we need to update self.log_level as that is
        # what updates the actual log level in self.log.
        self.default_config.Global.log_level = self.log_level

        # No GUI integration by default
        self.default_config.Global.wthread = False
        self.default_config.Global.q4thread = False
        self.default_config.Global.gthread = False

    def create_command_line_config(self):
        """Create and return a command line config loader."""
        return IPythonAppCLConfigLoader(
            description=ipython_desc,
            version=release.version)

    def post_load_command_line_config(self):
        """Do actions after loading cl config."""
        clc = self.command_line_config

        # Display the deprecation warnings about threaded shells
        if hasattr(clc.Global, 'pylab'):
            pylab_warning()
            del clc.Global['pylab']

    def load_file_config(self):
        if hasattr(self.command_line_config.Global, 'quick'):
            if self.command_line_config.Global.quick:
                self.file_config = Config()
                return
        super(IPythonApp, self).load_file_config()

    def post_load_file_config(self):
        if hasattr(self.command_line_config.Global, 'extra_extension'):
            if not hasattr(self.file_config.Global, 'extensions'):
                self.file_config.Global.extensions = []
            self.file_config.Global.extensions.append(
                self.command_line_config.Global.extra_extension)
            del self.command_line_config.Global.extra_extension

    def pre_construct(self):
        config = self.master_config

        if hasattr(config.Global, 'classic'):
            if config.Global.classic:
                config.InteractiveShell.cache_size = 0
                config.InteractiveShell.pprint = 0
                config.InteractiveShell.prompt_in1 = '>>> '
                config.InteractiveShell.prompt_in2 = '... '
                config.InteractiveShell.prompt_out = ''
                config.InteractiveShell.separate_in = \
                    config.InteractiveShell.separate_out = \
                    config.InteractiveShell.separate_out2 = ''
                config.InteractiveShell.colors = 'NoColor'
                config.InteractiveShell.xmode = 'Plain'

        if hasattr(config.Global, 'nosep'):
            if config.Global.nosep:
                config.InteractiveShell.separate_in = \
                config.InteractiveShell.separate_out = \
                config.InteractiveShell.separate_out2 = ''

        # if there is code of files to run from the cmd line, don't interact
        # unless the -i flag (Global.force_interact) is true.
        code_to_run = config.Global.get('code_to_run','')
        file_to_run = False
        if len(self.extra_args)>=1:
            if self.extra_args[0]:
                file_to_run = True
        if file_to_run or code_to_run:
            if not config.Global.force_interact:
                config.Global.interact = False

    def construct(self):
        # I am a little hesitant to put these into InteractiveShell itself.
        # But that might be the place for them
        sys.path.insert(0, '')

        # Create an InteractiveShell instance
        self.shell = InteractiveShell(
            parent=None,
            config=self.master_config
        )

    def post_construct(self):
        """Do actions after construct, but before starting the app."""
        config = self.master_config
        
        # shell.display_banner should always be False for the terminal 
        # based app, because we call shell.show_banner() by hand below
        # so the banner shows *before* all extension loading stuff.
        self.shell.display_banner = False

        if config.Global.display_banner and \
            config.Global.interact:
            self.shell.show_banner()

        # Make sure there is a space below the banner.
        if self.log_level <= logging.INFO: print

        # Now a variety of things that happen after the banner is printed.
        self._enable_gui()
        self._load_extensions()
        self._run_exec_lines()
        self._run_exec_files()
        self._run_cmd_line_code()

    def _enable_gui(self):
        """Enable GUI event loop integration."""
        config = self.master_config
        try:
            # Enable GUI integration
            if config.Global.wthread:
                self.log.info("Enabling wx GUI event loop integration")
                inputhook.enable_wx(app=True)
            elif config.Global.q4thread:
                self.log.info("Enabling Qt4 GUI event loop integration")
                inputhook.enable_qt4(app=True)
            elif config.Global.gthread:
                self.log.info("Enabling GTK GUI event loop integration")
                inputhook.enable_gtk(app=True)
        except:
            self.log.warn("Error in enabling GUI event loop integration:")
            self.shell.showtraceback()

    def _load_extensions(self):
        """Load all IPython extensions in Global.extensions.

        This uses the :meth:`InteractiveShell.load_extensions` to load all
        the extensions listed in ``self.master_config.Global.extensions``.
        """
        try:
            if hasattr(self.master_config.Global, 'extensions'):
                self.log.debug("Loading IPython extensions...")
                extensions = self.master_config.Global.extensions
                for ext in extensions:
                    try:
                        self.log.info("Loading IPython extension: %s" % ext)                        
                        self.shell.load_extension(ext)
                    except:
                        self.log.warn("Error in loading extension: %s" % ext)
                        self.shell.showtraceback()
        except:
            self.log.warn("Unknown error in loading extensions:")
            self.shell.showtraceback()

    def _run_exec_lines(self):
        """Run lines of code in Global.exec_lines in the user's namespace."""
        try:
            if hasattr(self.master_config.Global, 'exec_lines'):
                self.log.debug("Running code from Global.exec_lines...")
                exec_lines = self.master_config.Global.exec_lines
                for line in exec_lines:
                    try:
                        self.log.info("Running code in user namespace: %s" % line)
                        self.shell.runlines(line)
                    except:
                        self.log.warn("Error in executing line in user namespace: %s" % line)
                        self.shell.showtraceback()
        except:
            self.log.warn("Unknown error in handling Global.exec_lines:")
            self.shell.showtraceback()

    def _exec_file(self, fname):
        full_filename = filefind(fname, ['.', self.ipythondir])
        if os.path.isfile(full_filename):
            if full_filename.endswith('.py'):
                self.log.info("Running file in user namespace: %s" % full_filename)
                self.shell.safe_execfile(full_filename, self.shell.user_ns)
            elif full_filename.endswith('.ipy'):
                self.log.info("Running file in user namespace: %s" % full_filename)
                self.shell.safe_execfile_ipy(full_filename)
            else:
                self.log.warn("File does not have a .py or .ipy extension: <%s>" % full_filename)

    def _run_exec_files(self):
        try:
            if hasattr(self.master_config.Global, 'exec_files'):
                self.log.debug("Running files in Global.exec_files...")
                exec_files = self.master_config.Global.exec_files
                for fname in exec_files:
                    self._exec_file(fname)
        except:
            self.log.warn("Unknown error in handling Global.exec_files:")
            self.shell.showtraceback()

    def _run_cmd_line_code(self):
        if hasattr(self.master_config.Global, 'code_to_run'):
            line = self.master_config.Global.code_to_run
            try:
                self.log.info("Running code given at command line (-c): %s" % line)
                self.shell.runlines(line)
            except:
                self.log.warn("Error in executing line in user namespace: %s" % line)
                self.shell.showtraceback()
            return
        # Like Python itself, ignore the second if the first of these is present
        try:
            fname = self.extra_args[0]
        except:
            pass
        else:
            try:
                self._exec_file(fname)
            except:
                self.log.warn("Error in executing file in user namespace: %s" % fname)
                self.shell.showtraceback()

    def start_app(self):
        if self.master_config.Global.interact:
            self.log.debug("Starting IPython's mainloop...")
            self.shell.mainloop()
Example #2
0
class IPythonApp(Application):
    name = u'ipython'
    #: argparse formats better the 'usage' than the 'description' field
    description = None
    usage = usage.cl_usage
    command_line_loader = IPAppConfigLoader
    default_config_file_name = default_config_file_name
    crash_handler_class = IPAppCrashHandler

    def create_default_config(self):
        super(IPythonApp, self).create_default_config()
        # Eliminate multiple lookups
        Global = self.default_config.Global

        # Set all default values
        Global.display_banner = True
        
        # If the -c flag is given or a file is given to run at the cmd line
        # like "ipython foo.py", normally we exit without starting the main
        # loop.  The force_interact config variable allows a user to override
        # this and interact.  It is also set by the -i cmd line flag, just
        # like Python.
        Global.force_interact = False

        # By default always interact by starting the IPython mainloop.
        Global.interact = True

        # No GUI integration by default
        Global.gui = False
        # Pylab off by default
        Global.pylab = False

        # Deprecated versions of gui support that used threading, we support
        # them just for bacwards compatibility as an alternate spelling for
        # '--gui X'
        Global.qthread = False
        Global.q4thread = False
        Global.wthread = False
        Global.gthread = False

    def load_file_config(self):
        if hasattr(self.command_line_config.Global, 'quick'):
            if self.command_line_config.Global.quick:
                self.file_config = Config()
                return
        super(IPythonApp, self).load_file_config()

    def post_load_file_config(self):
        if hasattr(self.command_line_config.Global, 'extra_extension'):
            if not hasattr(self.file_config.Global, 'extensions'):
                self.file_config.Global.extensions = []
            self.file_config.Global.extensions.append(
                self.command_line_config.Global.extra_extension)
            del self.command_line_config.Global.extra_extension

    def pre_construct(self):
        config = self.master_config

        if hasattr(config.Global, 'classic'):
            if config.Global.classic:
                config.InteractiveShell.cache_size = 0
                config.InteractiveShell.pprint = 0
                config.InteractiveShell.prompt_in1 = '>>> '
                config.InteractiveShell.prompt_in2 = '... '
                config.InteractiveShell.prompt_out = ''
                config.InteractiveShell.separate_in = \
                    config.InteractiveShell.separate_out = \
                    config.InteractiveShell.separate_out2 = ''
                config.InteractiveShell.colors = 'NoColor'
                config.InteractiveShell.xmode = 'Plain'

        if hasattr(config.Global, 'nosep'):
            if config.Global.nosep:
                config.InteractiveShell.separate_in = \
                config.InteractiveShell.separate_out = \
                config.InteractiveShell.separate_out2 = ''

        # if there is code of files to run from the cmd line, don't interact
        # unless the -i flag (Global.force_interact) is true.
        code_to_run = config.Global.get('code_to_run','')
        file_to_run = False
        if self.extra_args and self.extra_args[0]:
                file_to_run = True
        if file_to_run or code_to_run:
            if not config.Global.force_interact:
                config.Global.interact = False

    def construct(self):
        # I am a little hesitant to put these into InteractiveShell itself.
        # But that might be the place for them
        sys.path.insert(0, '')

        # Create an InteractiveShell instance
        self.shell = InteractiveShell(None, self.master_config)

    def post_construct(self):
        """Do actions after construct, but before starting the app."""
        config = self.master_config
        
        # shell.display_banner should always be False for the terminal 
        # based app, because we call shell.show_banner() by hand below
        # so the banner shows *before* all extension loading stuff.
        self.shell.display_banner = False
        if config.Global.display_banner and \
            config.Global.interact:
            self.shell.show_banner()

        # Make sure there is a space below the banner.
        if self.log_level <= logging.INFO: print

        # Now a variety of things that happen after the banner is printed.
        self._enable_gui_pylab()
        self._load_extensions()
        self._run_exec_lines()
        self._run_exec_files()
        self._run_cmd_line_code()

    def _enable_gui_pylab(self):
        """Enable GUI event loop integration, taking pylab into account."""
        Global = self.master_config.Global

        # Select which gui to use
        if Global.gui:
            gui = Global.gui
        # The following are deprecated, but there's likely to be a lot of use
        # of this form out there, so we might as well support it for now.  But
        # the --gui option above takes precedence.
        elif Global.wthread:
            gui = inputhook.GUI_WX
        elif Global.qthread:
            gui = inputhook.GUI_QT
        elif Global.gthread:
            gui = inputhook.GUI_GTK
        else:
            gui = None

        # Using --pylab will also require gui activation, though which toolkit
        # to use may be chosen automatically based on mpl configuration.
        if Global.pylab:
            activate = self.shell.enable_pylab
            if Global.pylab == 'auto':
                gui = None
            else:
                gui = Global.pylab
        else:
            # Enable only GUI integration, no pylab
            activate = inputhook.enable_gui

        if gui or Global.pylab:
            try:
                self.log.info("Enabling GUI event loop integration, "
                              "toolkit=%s, pylab=%s" % (gui, Global.pylab) )
                activate(gui)
            except:
                self.log.warn("Error in enabling GUI event loop integration:")
                self.shell.showtraceback()

    def _load_extensions(self):
        """Load all IPython extensions in Global.extensions.

        This uses the :meth:`InteractiveShell.load_extensions` to load all
        the extensions listed in ``self.master_config.Global.extensions``.
        """
        try:
            if hasattr(self.master_config.Global, 'extensions'):
                self.log.debug("Loading IPython extensions...")
                extensions = self.master_config.Global.extensions
                for ext in extensions:
                    try:
                        self.log.info("Loading IPython extension: %s" % ext)                        
                        self.shell.load_extension(ext)
                    except:
                        self.log.warn("Error in loading extension: %s" % ext)
                        self.shell.showtraceback()
        except:
            self.log.warn("Unknown error in loading extensions:")
            self.shell.showtraceback()

    def _run_exec_lines(self):
        """Run lines of code in Global.exec_lines in the user's namespace."""
        try:
            if hasattr(self.master_config.Global, 'exec_lines'):
                self.log.debug("Running code from Global.exec_lines...")
                exec_lines = self.master_config.Global.exec_lines
                for line in exec_lines:
                    try:
                        self.log.info("Running code in user namespace: %s" %
                                      line)
                        self.shell.runlines(line)
                    except:
                        self.log.warn("Error in executing line in user "
                                      "namespace: %s" % line)
                        self.shell.showtraceback()
        except:
            self.log.warn("Unknown error in handling Global.exec_lines:")
            self.shell.showtraceback()

    def _exec_file(self, fname):
        full_filename = filefind(fname, [u'.', self.ipython_dir])
        if os.path.isfile(full_filename):
            if full_filename.endswith(u'.py'):
                self.log.info("Running file in user namespace: %s" %
                              full_filename)
                # Ensure that __file__ is always defined to match Python behavior
                self.shell.user_ns['__file__'] = fname
                try:
                    self.shell.safe_execfile(full_filename, self.shell.user_ns)
                finally:
                    del self.shell.user_ns['__file__']
            elif full_filename.endswith('.ipy'):
                self.log.info("Running file in user namespace: %s" %
                              full_filename)
                self.shell.safe_execfile_ipy(full_filename)
            else:
                self.log.warn("File does not have a .py or .ipy extension: <%s>"
                               % full_filename)
    def _run_exec_files(self):
        try:
            if hasattr(self.master_config.Global, 'exec_files'):
                self.log.debug("Running files in Global.exec_files...")
                exec_files = self.master_config.Global.exec_files
                for fname in exec_files:
                    self._exec_file(fname)
        except:
            self.log.warn("Unknown error in handling Global.exec_files:")
            self.shell.showtraceback()

    def _run_cmd_line_code(self):
        if hasattr(self.master_config.Global, 'code_to_run'):
            line = self.master_config.Global.code_to_run
            try:
                self.log.info("Running code given at command line (-c): %s" %
                              line)
                self.shell.runlines(line)
            except:
                self.log.warn("Error in executing line in user namespace: %s" %
                              line)
                self.shell.showtraceback()
            return
        # Like Python itself, ignore the second if the first of these is present
        try:
            fname = self.extra_args[0]
        except:
            pass
        else:
            try:
                self._exec_file(fname)
            except:
                self.log.warn("Error in executing file in user namespace: %s" %
                              fname)
                self.shell.showtraceback()

    def start_app(self):
        if self.master_config.Global.interact:
            self.log.debug("Starting IPython's mainloop...")
            self.shell.mainloop()
        else:
            self.log.debug("IPython not interactive, start_app is no-op...")