コード例 #1
0
def runcell(cellname, filename=None, post_mortem=False):
    """
    Run a code cell from an editor as a file.

    Currently looks for code in an `ipython` property called `cell_code`.
    This property must be set by the editor prior to calling this function.
    This function deletes the contents of `cell_code` upon completion.

    Parameters
    ----------
    cellname : str or int
        Cell name or index.
    filename : str
        Needed to allow for proper traceback links.
    """
    if filename is None:
        filename = get_current_file_name()
        if filename is None:
            return
    else:
        # get_debugger replaces \\ by / so we must undo that here
        # Otherwise code caching doesn't work
        if os.name == 'nt':
            filename = filename.replace('/', '\\')
    try:
        filename = filename.decode('utf-8')
    except (UnicodeError, TypeError, AttributeError):
        # UnicodeError, TypeError --> eventually raised in Python 2
        # AttributeError --> systematically raised in Python 3
        pass
    ipython_shell = get_ipython()
    try:
        # Get code from spyder
        cell_code = frontend_request().run_cell(cellname, filename)
    except Exception:
        _print("This command failed to be executed because an error occurred"
               " while trying to get the cell code from Spyder's"
               " editor. The error was:\n\n")
        get_ipython().showtraceback(exception_only=True)
        return

    if not cell_code or cell_code.strip() == '':
        _print("Nothing to execute, this cell is empty.\n")
        return

    # Trigger `post_execute` to exit the additional pre-execution.
    # See Spyder PR #7310.
    ipython_shell.events.trigger('post_execute')
    try:
        file_code = get_file_code(filename)
    except Exception:
        file_code = None
    with NamespaceManager(filename,
                          current_namespace=True,
                          file_code=file_code) as (ns_globals, ns_locals):
        exec_code(cell_code,
                  filename,
                  ns_globals,
                  ns_locals,
                  post_mortem=post_mortem)
コード例 #2
0
ファイル: spydercustomize.py プロジェクト: ubuntu11/spyder
def exec_code(code, filename, ns_globals, ns_locals=None, post_mortem=False):
    """Execute code and display any exception."""
    # Tell IPython to hide this frame (>7.16)
    __tracebackhide__ = True
    global SHOW_INVALID_SYNTAX_MSG

    if PY2:
        filename = encode(filename)
        code = encode(code)

    ipython_shell = get_ipython()
    is_ipython = os.path.splitext(filename)[1] == '.ipy'
    try:
        if not is_ipython:
            # TODO: remove the try-except and let the SyntaxError raise
            # Because there should not be ipython code in a python file
            try:
                compiled = compile(
                    transform_cell(code, indent_only=True), filename, 'exec')
            except SyntaxError as e:
                try:
                    compiled = compile(transform_cell(code), filename, 'exec')
                except SyntaxError:
                    if PY2:
                        raise e
                    else:
                        # Need to call exec to avoid Syntax Error in Python 2.
                        # TODO: remove exec when dropping Python 2 support.
                        exec("raise e from None")
                else:
                    if SHOW_INVALID_SYNTAX_MSG:
                        _print(
                            "\nWARNING: This is not valid Python code. "
                            "If you want to use IPython magics, "
                            "flexible indentation, and prompt removal, "
                            "we recommend that you save this file with the "
                            ".ipy extension.\n")
                        SHOW_INVALID_SYNTAX_MSG = False
        else:
            compiled = compile(transform_cell(code), filename, 'exec')
        exec(compiled, ns_globals, ns_locals)
    except SystemExit as status:
        # ignore exit(0)
        if status.code:
            ipython_shell.showtraceback(exception_only=True)
    except BaseException as error:
        if (isinstance(error, bdb.BdbQuit)
                and ipython_shell.kernel._pdb_obj):
            # Ignore BdbQuit if we are debugging, as it is expected.
            ipython_shell.kernel._pdb_obj = None
        elif post_mortem and isinstance(error, Exception):
            error_type, error, tb = sys.exc_info()
            post_mortem_excepthook(error_type, error, tb)
        else:
            # We ignore the call to exec
            ipython_shell.showtraceback(tb_offset=1)
    __tracebackhide__ = "__pdb_exit__"
コード例 #3
0
def get_current_file_name():
    """Get the current file name."""
    try:
        return frontend_request().current_filename()
    except Exception:
        _print("This command failed to be executed because an error occurred"
               " while trying to get the current file name from Spyder's"
               " editor. The error was:\n\n")
        get_ipython().showtraceback(exception_only=True)
        return None
コード例 #4
0
def exec_code(code, filename, ns_globals, ns_locals=None):
    """Execute code and display any exception."""
    global SHOW_INVALID_SYNTAX_MSG

    if PY2:
        filename = encode(filename)
        code = encode(code)

    ipython_shell = get_ipython()
    is_ipython = os.path.splitext(filename)[1] == '.ipy'
    try:
        if not is_ipython:
            # TODO: remove the try-except and let the SyntaxError raise
            # Because there should not be ipython code in a python file
            try:
                compiled = compile(code, filename, 'exec')
            except SyntaxError as e:
                try:
                    compiled = compile(transform_cell(code), filename, 'exec')
                except SyntaxError:
                    if PY2:
                        raise e
                    else:
                        # Need to call exec to avoid Syntax Error in Python 2.
                        # TODO: remove exec when dropping Python 2 support.
                        exec("raise e from None")
                else:
                    if SHOW_INVALID_SYNTAX_MSG:
                        _print(
                            "\nWARNING: This is not valid Python code. "
                            "If you want to use IPython magics, "
                            "flexible indentation, and prompt removal, "
                            "please save this file with the .ipy extension. "
                            "This will be an error in a future version of "
                            "Spyder.\n")
                        SHOW_INVALID_SYNTAX_MSG = False
        else:
            compiled = compile(transform_cell(code), filename, 'exec')

        exec(compiled, ns_globals, ns_locals)
    except SystemExit as status:
        # ignore exit(0)
        if status.code:
            ipython_shell.showtraceback(exception_only=True)
    except BaseException as error:
        if (isinstance(error, bdb.BdbQuit) and ipython_shell.kernel._pdb_obj):
            # Ignore BdbQuit if we are debugging, as it is expected.
            ipython_shell.kernel._pdb_obj = None
        else:
            # We ignore the call to exec
            ipython_shell.showtraceback(tb_offset=1)
コード例 #5
0
 def _cmdloop(self):
     """Modifies the error text."""
     while True:
         try:
             # keyboard interrupts allow for an easy way to cancel
             # the current command, so allow them during interactive input
             self.allow_kbdint = True
             self.cmdloop()
             self.allow_kbdint = False
             break
         except KeyboardInterrupt:
             _print("--KeyboardInterrupt--\n"
                    "For copying text while debugging, use Ctrl+Shift+C",
                    file=self.stdout)
コード例 #6
0
ファイル: spyderpdb.py プロジェクト: leogott/spyder
 def _cmdloop(self):
     """Modifies the error text."""
     while True:
         try:
             # keyboard interrupts allow for an easy way to cancel
             # the current command, so allow them during interactive input
             self.allow_kbdint = True
             self.cmdloop()
             self.allow_kbdint = False
             break
         except KeyboardInterrupt:
             _print("--KeyboardInterrupt--\n"
                    "For copying text while debugging, use Ctrl+Shift+C",
                    file=self.stdout)
         except Exception:
             try:
                 frontend_request(blocking=True).set_debug_state(False)
             except (CommError, TimeoutError):
                 logger.debug(
                     "Could not send debugging state to the frontend.")
             raise
コード例 #7
0
def post_mortem_excepthook(type, value, tb):
    """
    For post mortem exception handling, print a banner and enable post
    mortem debugging.
    """
    clear_post_mortem()
    ipython_shell = get_ipython()
    ipython_shell.showtraceback((type, value, tb))
    p = pdb.Pdb(ipython_shell.colors)

    if not type == SyntaxError:
        # wait for stderr to print (stderr.flush does not work in this case)
        time.sleep(0.1)
        _print('*' * 40)
        _print('Entering post mortem debugging...')
        _print('*' * 40)
        #  add ability to move between frames
        p.send_initial_notification = False
        p.reset()
        frame = tb.tb_frame
        prev = frame
        while frame.f_back:
            prev = frame
            frame = frame.f_back
        frame = prev
        # wait for stdout to print
        time.sleep(0.1)
        p.interaction(frame, tb)
コード例 #8
0
 def _patched_preparation_data(name):
     """
     Patched get_preparation_data to work when all variables are
     removed before execution.
     """
     try:
         d = _old_preparation_data(name)
     except AttributeError:
         main_module = sys.modules['__main__']
         # Any string for __spec__ does the job
         main_module.__spec__ = ''
         d = _old_preparation_data(name)
     # On windows, there is no fork, so we need to save the main file
     # and import it
     if (os.name == 'nt' and 'init_main_from_path' in d
             and not os.path.exists(d['init_main_from_path'])):
         _print(
             "Warning: multiprocessing may need the main file to exist. "
             "Please save {}".format(d['init_main_from_path']))
         # Remove path as the subprocess can't do anything with it
         del d['init_main_from_path']
     return d
コード例 #9
0
ファイル: umr.py プロジェクト: spyder-ide/spyder-kernels
    def run(self):
        """
        Delete user modules to force Python to deeply reload them

        Do not del modules which are considered as system modules, i.e.
        modules installed in subdirectories of Python interpreter's binary
        Do not del C modules
        """
        self.modnames_to_reload = []
        for modname, module in list(sys.modules.items()):
            if modname not in self.previous_modules:
                # Decide if a module can be reloaded or not
                if self.is_module_reloadable(module, modname):
                    self.modnames_to_reload.append(modname)
                    del sys.modules[modname]
                else:
                    continue

        # Report reloaded modules
        if self.verbose and self.modnames_to_reload:
            modnames = self.modnames_to_reload
            _print("\x1b[4;33m%s\x1b[24m%s\x1b[0m" %
                   ("Reloaded modules", ": " + ", ".join(modnames)))
コード例 #10
0
def runfile(filename=None,
            args=None,
            wdir=None,
            namespace=None,
            post_mortem=False,
            current_namespace=False):
    """
    Run filename
    args: command line arguments (string)
    wdir: working directory
    namespace: namespace for execution
    post_mortem: boolean, whether to enter post-mortem mode on error
    current_namespace: if true, run the file in the current namespace
    """
    # Tell IPython to hide this frame (>7.16)
    __tracebackhide__ = True
    ipython_shell = get_ipython()
    if filename is None:
        filename = get_current_file_name()
        if filename is None:
            return
    else:
        # get_debugger replaces \\ by / so we must undo that here
        # Otherwise code caching doesn't work
        if os.name == 'nt':
            filename = filename.replace('/', '\\')

    try:
        filename = filename.decode('utf-8')
    except (UnicodeError, TypeError, AttributeError):
        # UnicodeError, TypeError --> eventually raised in Python 2
        # AttributeError --> systematically raised in Python 3
        pass
    if PY2:
        filename = encode(filename)
    if __umr__.enabled:
        __umr__.run()
    if args is not None and not isinstance(args, basestring):
        raise TypeError("expected a character buffer object")
    try:
        file_code = get_file_code(filename)
    except Exception:
        _print("This command failed to be executed because an error occurred"
               " while trying to get the file code from Spyder's"
               " editor. The error was:\n\n")
        get_ipython().showtraceback(exception_only=True)
        return
    if file_code is None:
        _print("Could not get code from editor.\n")
        return

    with NamespaceManager(filename,
                          namespace,
                          current_namespace,
                          file_code=file_code) as (ns_globals, ns_locals):
        sys.argv = [filename]
        if args is not None:
            for arg in shlex.split(args):
                sys.argv.append(arg)
        if wdir is not None:
            if PY2:
                try:
                    wdir = wdir.decode('utf-8')
                except (UnicodeError, TypeError):
                    # UnicodeError, TypeError --> eventually raised in Python 2
                    pass
            if os.path.isdir(wdir):
                os.chdir(wdir)
                # See https://github.com/spyder-ide/spyder/issues/13632
                if "multiprocessing.process" in sys.modules:
                    try:
                        import multiprocessing.process
                        multiprocessing.process.ORIGINAL_DIR = os.path.abspath(
                            wdir)
                    except Exception:
                        pass
            else:
                _print("Working directory {} doesn't exist.\n".format(wdir))

        if __umr__.has_cython:
            # Cython files
            with io.open(filename, encoding='utf-8') as f:
                ipython_shell.run_cell_magic('cython', '', f.read())
        else:
            exec_code(file_code,
                      filename,
                      ns_globals,
                      ns_locals,
                      post_mortem=post_mortem)

        sys.argv = ['']
コード例 #11
0
def _exec_cell(cellname,
               filename=None,
               post_mortem=False,
               stack_depth=0,
               exec_fun=None):
    """
    Execute a code cell with a given exec function.
    """
    # Tell IPython to hide this frame (>7.16)
    __tracebackhide__ = True
    if filename is None:
        filename = get_current_file_name()
        if filename is None:
            return
    else:
        # get_debugger replaces \\ by / so we must undo that here
        # Otherwise code caching doesn't work
        if os.name == 'nt':
            filename = filename.replace('/', '\\')
    try:
        filename = filename.decode('utf-8')
    except (UnicodeError, TypeError, AttributeError):
        # UnicodeError, TypeError --> eventually raised in Python 2
        # AttributeError --> systematically raised in Python 3
        pass
    ipython_shell = get_ipython()
    try:
        # Get code from spyder
        cell_code = frontend_request(blocking=True).run_cell(
            cellname, filename)
    except Exception:
        _print("This command failed to be executed because an error occurred"
               " while trying to get the cell code from Spyder's"
               " editor. The error was:\n\n")
        get_ipython().showtraceback(exception_only=True)
        return

    if not cell_code or cell_code.strip() == '':
        _print("Nothing to execute, this cell is empty.\n")
        return

    # Trigger `post_execute` to exit the additional pre-execution.
    # See Spyder PR #7310.
    ipython_shell.events.trigger('post_execute')
    try:
        file_code = get_file_code(filename, save_all=False)
    except Exception:
        file_code = None

    # Normalise the filename
    filename = os.path.abspath(filename)
    filename = os.path.normcase(filename)

    with NamespaceManager(filename,
                          current_namespace=True,
                          file_code=file_code,
                          stack_depth=stack_depth + 1) as (ns_globals,
                                                           ns_locals):
        return exec_code(cell_code,
                         filename,
                         ns_globals,
                         ns_locals,
                         post_mortem=post_mortem,
                         exec_fun=exec_fun,
                         capture_last_expression=True)