Ejemplo n.º 1
0
    def event_processor(self, frame, event, event_arg, prompt='trepan3k'):
        'command event processor: reading a commands do something with them.'
        self.frame = frame
        self.event = event
        self.event_arg = event_arg

        filename = frame.f_code.co_filename
        lineno = frame.f_lineno
        line = linecache.getline(filename, lineno, frame.f_globals)
        if not line:
            opts = {
                'output': 'plain',
                'reload_on_change': self.settings('reload'),
                'strip_nl': False
            }
            m = re.search('^<frozen (.*)>', filename)
            if m and m.group(1):
                filename = pyficache.unmap_file(m.group(1))
            line = pyficache.getline(filename, lineno, opts)
        self.current_source_text = line
        if self.settings('skip') is not None:
            if Mbytecode.is_def_stmt(line, frame):
                return True
            if Mbytecode.is_class_def(line, frame):
                return True
            pass
        self.thread_name = Mthread.current_thread_name()
        self.frame_thread_name = self.thread_name
        self.set_prompt(prompt)
        self.process_commands()
        if filename == '<string>': pyficache.remove_remap_file('<string>')
        return True
Ejemplo n.º 2
0
def format_location(proc_obj):
    """Show where we are. GUI's and front-end interfaces often
    use this to update displays. So it is helpful to make sure
    we give at least some place that's located in a file.
    """
    i_stack = proc_obj.curindex
    if i_stack is None or proc_obj.stack is None:
        return False
    location = {}
    core_obj = proc_obj.core
    dbgr_obj = proc_obj.debugger

    # Evaluation routines like "exec" don't show useful location
    # info. In these cases, we will use the position before that in
    # the stack.  Hence the looping below which in practices loops
    # once and sometimes twice.
    remapped_file = None
    while i_stack >= 0:
        frame_lineno = proc_obj.stack[i_stack]
        i_stack -= 1
        frame, lineno = frame_lineno

        filename = Mstack.frame2file(core_obj, frame)

        location['filename'] = filename
        location['fn_name'] = frame.f_code.co_name
        location['lineno'] = lineno

        if '<string>' == filename and dbgr_obj.eval_string:
            remapped_file = filename
            filename = pyficache.unmap_file(filename)
            if '<string>' == filename:
                fd = tempfile.NamedTemporaryFile(suffix='.py',
                                                 prefix='eval_string',
                                                 delete=False)
                fd.write(bytes(dbgr_obj.eval_string, 'UTF-8'))
                fd.close()
                pyficache.remap_file(fd.name, '<string>')
                filename = fd.name
                pass
            pass

        opts = {
            'reload_on_change': proc_obj.settings('reload'),
            'output': 'plain'
        }
        line = pyficache.getline(filename, lineno, opts)
        if not line:
            line = linecache.getline(filename, lineno,
                                     proc_obj.curframe.f_globals)
            pass

        if line and len(line.strip()) != 0:
            location['text'] = line
            pass
        if '<string>' != filename: break
        pass

    return location
Ejemplo n.º 3
0
def format_location(proc_obj):
    """Show where we are. GUI's and front-end interfaces often
    use this to update displays. So it is helpful to make sure
    we give at least some place that's located in a file.
    """
    i_stack = proc_obj.curindex
    if i_stack is None or proc_obj.stack is None:
        return False
    location = {}
    core_obj = proc_obj.core
    dbgr_obj = proc_obj.debugger

    # Evaluation routines like "exec" don't show useful location
    # info. In these cases, we will use the position before that in
    # the stack.  Hence the looping below which in practices loops
    # once and sometimes twice.
    remapped_file = None
    while i_stack >= 0:
        frame_lineno = proc_obj.stack[i_stack]
        i_stack -= 1
        frame, lineno = frame_lineno

        filename = Mstack.frame2file(core_obj, frame)

        location['filename'] = filename
        location['fn_name']  = frame.f_code.co_name
        location['lineno']   = lineno

        if '<string>' == filename and dbgr_obj.eval_string:
            remapped_file = filename
            filename = pyficache.unmap_file(filename)
            if '<string>' == filename:
                fd = tempfile.NamedTemporaryFile(suffix='.py',
                                                 prefix='eval_string',
                                                 delete=False)
                fd.write(bytes(dbgr_obj.eval_string, 'UTF-8'))
                fd.close()
                pyficache.remap_file(fd.name, '<string>')
                filename = fd.name
                pass
            pass

        opts = {
            'reload_on_change' : proc_obj.settings('reload'),
            'output'           : 'plain'
            }
        line = pyficache.getline(filename, lineno, opts)
        if not line:
            line = linecache.getline(filename, lineno,
                                     proc_obj.curframe.f_globals)
            pass

        if line and len(line.strip()) != 0:
            location['text'] = line
            pass
        if '<string>' != filename: break
        pass

    return location
Ejemplo n.º 4
0
    def event_processor(self, frame, event, event_arg, prompt="trepan3k"):
        """
        command event processor: reading a commands do something with them.

        See https://docs.python.org/3/library/sys.html#sys.settrace
        for how this protocol works and what the events means.

        Of particular note those is what we return:

            The local trace function should return a reference to
            itself (or to another function for further tracing in that
            scope), or None to turn off tracing in that scope.

            If there is any error occurred in the trace function, it
            will be unset, just like settrace(None) is called.
        """

        self.frame = frame
        self.event = event
        self.event_arg = event_arg

        filename = frame.f_code.co_filename
        lineno = frame.f_lineno
        line = linecache.getline(filename, lineno, frame.f_globals)
        if not line:
            opts = {
                "output": "plain",
                "reload_on_change": self.settings("reload"),
                "strip_nl": False,
            }
            m = re.search("^<frozen (.*)>", filename)
            if m and m.group(1):
                filename = pyficache.unmap_file(m.group(1))
            line = pyficache.getline(filename, lineno, opts)
        self.current_source_text = line
        if self.settings("skip") is not None:
            if is_def_stmt(line, frame):
                return self.event_processor
            if is_class_def(line, frame):
                return self.event_processor
            pass
        self.thread_name = Mthread.current_thread_name()
        self.frame_thread_name = self.thread_name
        self.set_prompt(prompt)
        self.process_commands()
        if filename == "<string>":
            pyficache.remove_remap_file("<string>")
        return self.event_processor
Ejemplo n.º 5
0
 def frame_setup(frame):
     filename = frame.f_code.co_filename
     lineno = frame.f_lineno
     line = linecache.getline(filename, lineno, frame.f_globals)
     if not line:
         opts = {
             "output": "plain",
             "reload_on_change": self.settings("reload"),
             "strip_nl": False,
         }
         m = re.search("^<frozen (.*)>", filename)
         if m and m.group(1):
             filename = pyficache.unmap_file(m.group(1))
         line = pyficache.getline(filename, lineno, opts)
     self.current_source_text = line
     return line, filename
Ejemplo n.º 6
0
    def canonic(self, filename):
        """ Turns `filename' into its canonic representation and returns this
        string. This allows a user to refer to a given file in one of several
        equivalent ways.

        Relative filenames need to be fully resolved, since the current working
        directory might change over the course of execution.

        If filename is enclosed in < ... >, then we assume it is
        one of the bogus internal Python names like <string> which is seen
        for example when executing "exec cmd".
        """

        if filename == "<" + filename[1:-1] + ">":
            return filename
        canonic = self.filename_cache.get(filename)
        if not canonic:
            lead_dir = filename.split(os.sep)[0]
            if lead_dir == os.curdir or lead_dir == os.pardir:
                # We may have invoked the program from a directory
                # other than where the program resides. filename is
                # relative to where the program resides. So make sure
                # to use that.
                canonic = os.path.abspath(os.path.join(self.main_dirname,
                                                       filename))
            else:
                canonic = os.path.abspath(filename)
                pass
            if not os.path.isfile(canonic):
                canonic = Mclifns.search_file(filename, self.search_path,
                                              self.main_dirname)
                # FIXME: is this is right for utter failure?
                if not canonic:
                    self.filename_cache[filename] = filename
                    return filename
                pass
            canonic = os.path.realpath(os.path.normcase(canonic))
            self.filename_cache[filename] = canonic
        canonic = pyficache.unmap_file(canonic)

        return canonic
Ejemplo n.º 7
0
    def run(self, args):
        filename, first, last = self.parse_list_cmd(args[1:])
        curframe = self.proc.curframe
        if filename is None: return
        m = re.search('^<frozen (.*)>', filename)
        if m and m.group(1):
            filename = m.group(1)
            canonic_filename = pyficache.unmap_file(filename)
        else:
            filename = pyc2py(filename)
            canonic_filename = os.path.realpath(os.path.normcase(filename))

        max_line = pyficache.size(filename)
        # FIXME: Should use the below:
        # max_line = pyficache.maxline(filename)

        # We now have range information. Do the listing.
        if max_line is None:
            self.errmsg('No file %s found' % filename)
            return

        if first > max_line:
            self.errmsg('Bad start line %d - file "%s" has only %d lines'
                        % (first, filename, max_line))
            return

        if last > max_line:
            self.msg('End position changed to last line %d ' % max_line)
            last = max_line

        bplist = self.core.bpmgr.bplist
        opts = {
            'reload_on_change' : self.settings['reload'],
            'output'           : self.settings['highlight'],
            'strip_nl'         : False,
            }

        if 'style' in self.settings:
            opts['style'] = self.settings['style']

        try:
            for lineno in range(first, last+1):
                line = pyficache.getline(filename, lineno, opts)
                if line is None:
                    line = linecache.getline(filename, lineno,
                                             self.proc.frame.f_globals)
                    pass
                if line is None:
                    self.msg('[EOF]')
                    break
                else:
                    line = line.rstrip('\n')
                    s = self.proc._saferepr(lineno).rjust(3)
                    if len(s) < 5: s += ' '
                    if (canonic_filename, lineno,) in list(bplist.keys()):
                        bp    = bplist[(canonic_filename, lineno,)][0]
                        a_pad = '%02d' % bp.number
                        s    += bp.icon_char()
                    else:
                        s    += ' '
                        a_pad = '  '
                        pass
                    if curframe and lineno == inspect.getlineno(curframe):
                        s += '->'
                        if 'plain' != self.settings['highlight']:
                            s = colorize('bold', s)
                    else:
                        s += a_pad
                        pass
                    self.msg(s + '\t' + line)
                    self.proc.list_lineno = lineno
                    pass
                pass
        except KeyboardInterrupt:
            pass
        return False
Ejemplo n.º 8
0
def print_location(proc_obj):
    """Show where we are. GUI's and front-end interfaces often
    use this to update displays. So it is helpful to make sure
    we give at least some place that's located in a file.
    """
    i_stack = proc_obj.curindex
    if i_stack is None or proc_obj.stack is None:
        return False
    core_obj = proc_obj.core
    dbgr_obj = proc_obj.debugger
    intf_obj = dbgr_obj.intf[-1]

    # Evaluation routines like "exec" don't show useful location
    # info. In these cases, we will use the position before that in
    # the stack.  Hence the looping below which in practices loops
    # once and sometimes twice.
    remapped_file = None
    while i_stack >= 0:
        frame_lineno = proc_obj.stack[i_stack]
        i_stack -= 1
        frame, lineno = frame_lineno

#         # Next check to see that local variable breadcrumb exists and
#         # has the magic dynamic value.
#         # If so, it's us and we don't normally show this.a
#         if 'breadcrumb' in frame.f_locals:
#             if self.run == frame.f_locals['breadcrumb']:
#                 break

        filename = Mstack.frame2file(core_obj, frame, canonic=False)
        if '<string>' == filename and dbgr_obj.eval_string:
            remapped_file = filename
            filename = pyficache.unmap_file(filename)
            if '<string>' == filename:
                fd = tempfile.NamedTemporaryFile(suffix='.py',
                                                 prefix='eval_string',
                                                 delete=False)
                with fd:
                    fd.write(dbgr_obj.eval_string)
                    fd.close()
                    pass
                pyficache.remap_file(fd.name, '<string>')
                filename = fd.name
                pass
            pass
        else:
            if filename in pyficache.file2file_remap:
                remapped_file = pyficache.unmap_file(filename)
                # FIXME: a remapped_file shouldn't be the same as its unmapped version
                if remapped_file == filename:
                    remapped_file = None
                    pass
                pass
            pass

        opts = {
            'reload_on_change' : proc_obj.settings('reload'),
            'output'           : proc_obj.settings('highlight')
            }

        if 'style' in proc_obj.debugger.settings:
            opts['style'] = proc_obj.settings('style')

        pyficache.update_cache(filename)
        line = pyficache.getline(filename, lineno, opts)
        if not line:
            # FIXME:
            # try with good ol linecache and consider fixing pyficache
            lines = linecache.getlines(filename)
            if lines:
                # FIXME: DRY code with version in cmdproc.py print_location
                prefix = os.path.basename(filename).split('.')[0]
                fd = tempfile.NamedTemporaryFile(suffix='.py',
                                                 prefix=prefix,
                                                 delete=False)
                with fd:
                    fd.write(''.join(lines))
                    remapped_file = fd.name
                    pyficache.remap_file(remapped_file, filename)
                fd.close()
                pass
            line = linecache.getline(filename, lineno,
                                     proc_obj.curframe.f_globals)
            pass

        fn_name = frame.f_code.co_name
        last_i  = frame.f_lasti
        print_source_location_info(intf_obj.msg, filename, lineno, fn_name,
                                   remapped_file = remapped_file,
                                   f_lasti = last_i)
        if line and len(line.strip()) != 0:
            if proc_obj.event:
                print_source_line(intf_obj.msg, lineno, line,
                                  proc_obj.event2short[proc_obj.event])
            pass
        if '<string>' != filename: break
        pass

    if proc_obj.event in ['return', 'exception']:
        val = proc_obj.event_arg
        intf_obj.msg('R=> %s' % proc_obj._saferepr(val))
        pass
    return True
Ejemplo n.º 9
0
    def run(self, args):
        proc = self.proc
        dbg_obj = self.core.debugger
        listsize = dbg_obj.settings["listsize"]
        filename, first, last = parse_list_cmd(proc, args, listsize)
        curframe = proc.curframe
        if filename is None:
            return
        filename = pyficache.unmap_file(
            pyficache.resolve_name_to_path(filename))

        # We now have range information. Do the listing.
        max_line = pyficache.size(filename)
        if max_line is None:
            bytecode = curframe.f_code

            if bytecode not in deparse_cache.keys():
                self.errmsg(
                    'No file %s found; using "deparse" command instead to show source'
                    % filename)
            proc.commands["deparse"].run(["deparse"])
            return

        canonic_filename = osp.realpath(osp.normcase(filename))

        if first > max_line:
            self.errmsg('Bad start line %d - file "%s" has only %d lines' %
                        (first, filename, max_line))
            return

        if last > max_line:
            self.msg("End position changed to last line %d " % max_line)
            last = max_line

        bplist = self.core.bpmgr.bplist
        opts = {
            "reload_on_change": self.settings["reload"],
            "output": self.settings["highlight"],
            "strip_nl": False,
        }

        if "style" in self.settings:
            opts["style"] = self.settings["style"]

        if first <= 0:
            first = 1
        try:
            for lineno in range(first, last + 1):
                line = pyficache.getline(filename, lineno, opts)
                if line is None:
                    line = linecache.getline(filename, lineno,
                                             proc.frame.f_globals)
                    pass
                if line is None:
                    self.msg("[EOF]")
                    break
                else:
                    line = line.rstrip("\n")
                    s = proc._saferepr(lineno).rjust(3)
                    if len(s) < 5:
                        s += " "
                    if (
                            canonic_filename,
                            lineno,
                    ) in list(bplist.keys()):
                        bp = bplist[(
                            canonic_filename,
                            lineno,
                        )][0]
                        a_pad = "%02d" % bp.number
                        s += bp.icon_char()
                    else:
                        s += " "
                        a_pad = "  "
                        pass
                    if curframe and lineno == inspect.getlineno(curframe):
                        s += "->"
                        if "plain" != self.settings["highlight"]:
                            s = colorize("bold", s)
                    else:
                        s += a_pad
                        pass
                    self.msg(s + "\t" + line)
                    proc.list_lineno = lineno
                    pass
                pass
            pass
        except KeyboardInterrupt:
            pass
        return False
Ejemplo n.º 10
0
def print_location(proc_obj):
    """Show where we are. GUI's and front-end interfaces often
    use this to update displays. So it is helpful to make sure
    we give at least some place that's located in a file.
    """
    i_stack = proc_obj.curindex
    if i_stack is None or proc_obj.stack is None:
        return False
    core_obj = proc_obj.core
    dbgr_obj = proc_obj.debugger
    intf_obj = dbgr_obj.intf[-1]

    # Evaluation routines like "exec" don't show useful location
    # info. In these cases, we will use the position before that in
    # the stack.  Hence the looping below which in practices loops
    # once and sometimes twice.
    remapped_file = None
    source_text = None
    while i_stack >= 0:
        frame_lineno = proc_obj.stack[i_stack]
        i_stack -= 1
        frame, lineno = frame_lineno

        #         # Next check to see that local variable breadcrumb exists and
        #         # has the magic dynamic value.
        #         # If so, it's us and we don't normally show this.a
        #         if 'breadcrumb' in frame.f_locals:
        #             if self.run == frame.f_locals['breadcrumb']:
        #                 break

        filename = Mstack.frame2file(core_obj, frame, canonic=False)
        if "<string>" == filename and dbgr_obj.eval_string:
            remapped_file = filename
            filename = pyficache.unmap_file(filename)
            if "<string>" == filename:
                remapped = source_tempfile_remap(
                    "eval_string",
                    dbgr_obj.eval_string,
                    tempdir=proc_obj.settings("tempdir"))
                pyficache.remap_file(filename, remapped)
                filename = remapped
                lineno = pyficache.unmap_file_line(filename, lineno)
                pass
            pass
        elif "<string>" == filename:
            source_text = deparse_fn(frame.f_code)
            filename = "<string: '%s'>" % source_text
            pass
        elif filename in proc_obj.file2file_remap:
            remapped_file = proc_obj.file2file_remap[filename]
        elif filename in pyficache.file2file_remap:
            remapped_file = pyficache.unmap_file(filename)
            # FIXME: a remapped_file shouldn't be the same as its unmapped version
            if remapped_file == filename:
                remapped_file = None
                pass
            pass
        elif pyficache.main.remap_re_hash:
            remapped_file = pyficache.remap_file_pat(
                filename, pyficache.main.remap_re_hash)

        opts = {
            "reload_on_change": proc_obj.settings("reload"),
            "output": proc_obj.settings("highlight"),
        }

        if "style" in proc_obj.debugger.settings:
            opts["style"] = proc_obj.settings("style")

        pyficache.update_cache(filename)
        line = pyficache.getline(filename, lineno, opts)
        if not line:
            if (not source_text and filename.startswith("<string: ")
                    and proc_obj.curframe.f_code):
                # Deparse the code object into a temp file and remap the line from code
                # into the corresponding line of the tempfile
                co = proc_obj.curframe.f_code
                tempdir = proc_obj.settings("tempdir")
                temp_filename, name_for_code = deparse_and_cache(
                    co, proc_obj.errmsg, tempdir=tempdir)
                lineno = 1
                # _, lineno = pyficache.unmap_file_line(temp_filename, lineno, True)
                if temp_filename:
                    filename = temp_filename
                pass

            else:
                # FIXME:
                if source_text:
                    lines = source_text.split("\n")
                    temp_name = "string-"
                else:
                    # try with good ol linecache and consider fixing pyficache
                    lines = linecache.getlines(filename)
                    temp_name = filename
                if lines:
                    # FIXME: DRY code with version in cmdproc.py print_location
                    prefix = osp.basename(temp_name).split(".")[0]
                    fd = tempfile.NamedTemporaryFile(
                        suffix=".py",
                        prefix=prefix,
                        delete=False,
                        dir=proc_obj.settings("tempdir"),
                    )
                    with fd:
                        fd.write("".join(lines))
                        remapped_file = fd.name
                        pyficache.remap_file(remapped_file, filename)
                    fd.close()
                    pass
                line = linecache.getline(filename, lineno,
                                         proc_obj.curframe.f_globals)
            pass

        fn_name = frame.f_code.co_name
        last_i = frame.f_lasti
        print_source_location_info(
            intf_obj.msg,
            filename,
            lineno,
            fn_name,
            remapped_file=remapped_file,
            f_lasti=last_i,
        )
        if line and len(line.strip()) != 0:
            if proc_obj.event:
                print_source_line(intf_obj.msg, lineno, line,
                                  proc_obj.event2short[proc_obj.event])
            pass
        if "<string>" != filename:
            break
        pass

    if proc_obj.event in ["return", "exception"]:
        val = proc_obj.event_arg
        intf_obj.msg("R=> %s" % proc_obj._saferepr(val))
        pass
    return True
Ejemplo n.º 11
0
def print_location(proc_obj):
    """Show where we are. GUI's and front-end interfaces often
    use this to update displays. So it is helpful to make sure
    we give at least some place that's located in a file.
    """
    i_stack = proc_obj.curindex
    if i_stack is None or proc_obj.stack is None:
        return False
    core_obj = proc_obj.core
    dbgr_obj = proc_obj.debugger
    intf_obj = dbgr_obj.intf[-1]

    # Evaluation routines like "exec" don't show useful location
    # info. In these cases, we will use the position before that in
    # the stack.  Hence the looping below which in practices loops
    # once and sometimes twice.
    remapped_file = None
    while i_stack >= 0:
        frame_lineno = proc_obj.stack[i_stack]
        i_stack -= 1
        frame, lineno = frame_lineno

        #         # Next check to see that local variable breadcrumb exists and
        #         # has the magic dynamic value.
        #         # If so, it's us and we don't normally show this.a
        #         if 'breadcrumb' in frame.f_locals:
        #             if self.run == frame.f_locals['breadcrumb']:
        #                 break

        filename = Mstack.frame2file(core_obj, frame, canonic=False)
        if '<string>' == filename and dbgr_obj.eval_string:
            remapped_file = filename
            filename = pyficache.unmap_file(filename)
            if '<string>' == filename:
                remapped = cmdfns.source_tempfile_remap(
                    'eval_string', dbgr_obj.eval_string)
                pyficache.remap_file(filename, remapped)
                filename = remapped
                pass
            pass
        else:
            m = re.search('^<frozen (.*)>', filename)
            if m and m.group(1) in pyficache.file2file_remap:
                remapped_file = pyficache.file2file_remap[m.group(1)]
                pass
            elif filename in pyficache.file2file_remap:
                remapped_file = pyficache.unmap_file(filename)
                # FIXME: a remapped_file shouldn't be the same as its unmapped version
                if remapped_file == filename:
                    remapped_file = None
                    pass
                pass
            elif m and m.group(1) in sys.modules:
                remapped_file = m.group(1)
                pyficache.remap_file(filename, remapped_file)
            pass

        code = frame.f_code
        fn_name = code.co_name
        last_i = frame.f_lasti

        opts = {
            'reload_on_change': proc_obj.settings('reload'),
            'output': proc_obj.settings('highlight')
        }

        if 'style' in proc_obj.debugger.settings:
            opts['style'] = proc_obj.settings('style')

        line = pyficache.getline(filename, lineno, opts)
        if not line:
            line = linecache.getline(filename, lineno,
                                     proc_obj.curframe.f_globals)
            if not line:
                m = re.search('^<frozen (.*)>', filename)
                if m and m.group(1):
                    remapped_file = m.group(1)
                    try_module = sys.modules.get(remapped_file)
                    if (try_module and inspect.ismodule(try_module)
                            and hasattr(try_module, '__file__')):
                        remapped_file = sys.modules[remapped_file].__file__
                        pyficache.remap_file(filename, remapped_file)
                        line = linecache.getline(remapped_file, lineno,
                                                 proc_obj.curframe.f_globals)
                    else:
                        remapped_file = m.group(1)
                        filename, line = cmdfns.deparse_getline(
                            code, remapped_file, lineno, opts)
                    pass
            pass

        try:
            match, reason = Mstack.check_path_with_frame(frame, filename)
            if not match:
                if filename not in warned_file_mismatches:
                    proc_obj.errmsg(reason)
                    warned_file_mismatches.add(filename)
        except:
            pass

        print_source_location_info(intf_obj.msg,
                                   filename,
                                   lineno,
                                   fn_name,
                                   remapped_file=remapped_file,
                                   f_lasti=last_i)

        if line and len(line.strip()) != 0:
            if proc_obj.event:
                print_source_line(intf_obj.msg, lineno, line,
                                  proc_obj.event2short[proc_obj.event])
            pass
        if '<string>' != filename: break
        pass

    if proc_obj.event in ['return', 'exception']:
        val = proc_obj.event_arg
        intf_obj.msg('R=> %s' % proc_obj._saferepr(val))
        pass
    return True
Ejemplo n.º 12
0
    def run(self, args):
        """Get file information"""
        if len(args) == 0:
            if not self.proc.curframe:
                self.errmsg("No frame - no default file.")
                return False
            filename = self.proc.curframe.f_code.co_filename
        else:
            filename = args[0]
            pass

        m = filename + " is"
        filename_cache = self.core.filename_cache
        if filename in filename_cache:
            m += " cached in debugger"
            if filename_cache[filename] != filename:
                m += " as:"
                m = Mmisc.wrapped_lines(m, filename_cache[filename] + ".", self.settings["width"])
            else:
                m += "."
                pass
            self.msg(m)
        else:
            matches = [file for file in file_list() if file.endswith(filename)]
            if len(matches) > 1:
                self.msg("Multiple files found ending filename string:")
                for match_file in matches:
                    self.msg("\t%s" % match_file)
                    pass
            elif len(matches) == 1:
                canonic_name = pyficache.unmap_file(matches[0])
                m += " matched debugger cache file:\n  " + canonic_name
                self.msg(m)
            else:
                self.msg(m + " not cached in debugger.")
            pass
        canonic_name = self.core.canonic(filename)
        self.msg(Mmisc.wrapped_lines("Canonic name:", canonic_name, self.settings["width"]))
        for name in (canonic_name, filename):
            if name in sys.modules:
                for key in [k for k, v in list(sys.modules.items()) if name == v]:
                    self.msg("module: %s", key)
                    pass
                pass
            pass
        for arg in args[1:]:
            processed_arg = False
            if arg in ["all", "size"]:
                if pyficache.size(canonic_name):
                    self.msg("File has %d lines." % pyficache.size(canonic_name))
                    pass
                processed_arg = True
                pass
            if arg in ["all", "sha1"]:
                self.msg("SHA1 is %s." % pyficache.sha1(canonic_name))
                processed_arg = True
                pass
            if arg in ["all", "brkpts"]:
                lines = pyficache.trace_line_numbers(canonic_name)
                if lines:
                    self.section("Possible breakpoint line numbers:")
                    fmt_lines = columnize.columnize(lines, ljust=False, arrange_vertical=False, lineprefix="  ")
                    self.msg(fmt_lines)
                    pass
                processed_arg = True
                pass
            if not processed_arg:
                self.errmsg("Don't understand sub-option %s." % arg)
                pass
            pass
        return
Ejemplo n.º 13
0
    def run(self, args):
        """**info files** [*filename* [**all** | **brkpts** | **lines** | **sha1** | **size**]]

        Show information about the current file. If no filename is
        given and the program is running then the current file associated
        with the current stack entry is used. Sub options which can be
        shown about a file are:

        * **brkpts** Line numbers where there are statement boundaries. These lines can be used in breakpoint commands.

        * **sha1**	A SHA1 hash of the source text.

        The following may be useful in comparing source code.

        * **size**	The number of lines in the file.

        * **all** All of the above information.
        """
        if len(args) == 0:
            if not self.proc.curframe:
                self.errmsg("No frame - no default file.")
                return False
            filename = self.proc.curframe.f_code.co_filename
        else:
            filename = args[0]
            pass

        m = filename + " is"
        filename_cache = self.core.filename_cache
        if filename in filename_cache:
            m += " cached in debugger"
            if filename_cache[filename] != filename:
                m += " as:"
                m = Mmisc.wrapped_lines(m, filename_cache[filename] + ".",
                                        self.settings["width"])
            else:
                m += "."
                pass
            self.msg(m)
        else:
            matches = [file for file in file_list() if file.endswith(filename)]
            if len(matches) > 1:
                self.msg("Multiple files found ending filename string:")
                for match_file in matches:
                    self.msg("\t%s" % match_file)
                    pass
            elif len(matches) == 1:
                canonic_name = pyficache.unmap_file(matches[0])
                m += " matched debugger cache file:\n  " + canonic_name
                self.msg(m)
            else:
                self.msg(m + " not cached in debugger.")
            pass
        canonic_name = self.core.canonic(filename)
        self.msg(
            Mmisc.wrapped_lines("Canonic name:", canonic_name,
                                self.settings["width"]))
        for name in (canonic_name, filename):
            if name in sys.modules:
                for key in [
                        k for k, v in list(sys.modules.items()) if name == v
                ]:
                    self.msg("module: %s", key)
                    pass
                pass
            pass
        for arg in args[1:]:
            processed_arg = False
            if arg in ["all", "size"]:
                if pyficache.size(canonic_name):
                    self.msg("File has %d lines." %
                             pyficache.size(canonic_name))
                    pass
                processed_arg = True
                pass
            if arg in ["all", "sha1"]:
                self.msg("SHA1 is %s." % pyficache.sha1(canonic_name))
                processed_arg = True
                pass
            if arg in ["all", "brkpts"]:
                lines = pyficache.trace_line_numbers(canonic_name)
                if lines:
                    self.section("Possible breakpoint line numbers:")
                    fmt_lines = columnize.columnize(
                        list(lines),
                        ljust=False,
                        arrange_vertical=False,
                        lineprefix="  ",
                    )
                    self.msg(fmt_lines)
                    pass
                processed_arg = True
                pass
            if not processed_arg:
                self.errmsg("Don't understand sub-option %s." % arg)
                pass
            pass
        return
Ejemplo n.º 14
0
    def run(self, args):
        filename, first, last = self.parse_list_cmd(args[1:])
        curframe = self.proc.curframe
        if filename is None: return
        filename = pyficache.unmap_file(pyc2py(filename))

        # We now have range information. Do the listing.
        max_line = pyficache.size(filename)
        if max_line is None:
            self.errmsg('No file %s found' % filename)
            return

        canonic_filename = os.path.realpath(os.path.normcase(filename))

        if first > max_line:
            self.errmsg('Bad start line %d - file "%s" has only %d lines'
                        % (first, filename, max_line))
            return

        if last > max_line:
            self.msg('End position changed to last line %d ' % max_line)
            last = max_line

        bplist = self.core.bpmgr.bplist
        opts = {
            'reload_on_change' : self.settings['reload'],
            'output'           : self.settings['highlight'],
            'strip_nl'         : False,
            }

        if 'style' in self.settings:
            opts['style'] = self.settings['style']

        try:
            for lineno in range(first, last+1):
                line = pyficache.getline(filename, lineno, opts)
                if line is None:
                    line = linecache.getline(filename, lineno,
                                             self.proc.frame.f_globals)
                    pass
                if line is None:
                    self.msg('[EOF]')
                    break
                else:
                    line = line.rstrip('\n')
                    s = self.proc._saferepr(lineno).rjust(3)
                    if len(s) < 5: s += ' '
                    if (canonic_filename, lineno,) in list(bplist.keys()):
                        bp    = bplist[(canonic_filename, lineno,)][0]
                        a_pad = '%02d' % bp.number
                        s    += bp.icon_char()
                    else:
                        s    += ' '
                        a_pad = '  '
                        pass
                    if curframe and lineno == inspect.getlineno(curframe):
                        s += '->'
                        if 'plain' != self.settings['highlight']:
                            s = colorize('bold', s)
                    else:
                        s += a_pad
                        pass
                    self.msg(s + '\t' + line)
                    self.proc.list_lineno = lineno
                    pass
                pass
        except KeyboardInterrupt:
            pass
        return False
Ejemplo n.º 15
0
def print_location(proc_obj):
    """Show where we are. GUI's and front-end interfaces often
    use this to update displays. So it is helpful to make sure
    we give at least some place that's located in a file.
    """
    i_stack = proc_obj.curindex
    if i_stack is None or proc_obj.stack is None:
        return False
    core_obj = proc_obj.core
    dbgr_obj = proc_obj.debugger
    intf_obj = dbgr_obj.intf[-1]

    # Evaluation routines like "exec" don't show useful location
    # info. In these cases, we will use the position before that in
    # the stack.  Hence the looping below which in practices loops
    # once and sometimes twice.
    remapped_file = None
    while i_stack >= 0:
        frame_lineno = proc_obj.stack[i_stack]
        i_stack -= 1
        frame, lineno = frame_lineno

#         # Next check to see that local variable breadcrumb exists and
#         # has the magic dynamic value.
#         # If so, it's us and we don't normally show this.a
#         if 'breadcrumb' in frame.f_locals:
#             if self.run == frame.f_locals['breadcrumb']:
#                 break

        filename = Mstack.frame2file(core_obj, frame)
        if '<string>' == filename and dbgr_obj.eval_string:
            remapped_file = filename
            filename = pyficache.unmap_file(filename)
            if '<string>' == filename:
                fd = tempfile.NamedTemporaryFile(suffix='.py',
                                                 prefix='eval_string',
                                                 delete=False)
                fd.write(dbgr_obj.eval_string)
                fd.close()
                pyficache.remap_file(fd.name, '<string>')
                filename = fd.name
                pass
            pass

        fn_name = frame.f_code.co_name
        print_source_location_info(intf_obj.msg, filename, lineno, fn_name,
                                   remapped_file = remapped_file)
                                   # proc_obj.curframe.f_lasti)

        opts = {
            'reload_on_change' : proc_obj.settings('reload'),
            'output'           : proc_obj.settings('highlight')
            }
        line = pyficache.getline(filename, lineno, opts)
        if not line:
            if sys.version_info[1] <= 4:
                # Python 2.4 and before doesn't have 3-arg getline
                line = linecache.getline(filename, lineno)
            else:
                line = linecache.getline(filename, lineno,
                                         proc_obj.curframe.f_globals)
                pass
            pass

        if line and len(line.strip()) != 0:
            if proc_obj.event:
                print_source_line(intf_obj.msg, lineno, line,
                                  proc_obj.event2short[proc_obj.event])
            pass
        if '<string>' != filename: break
        pass

    if proc_obj.event in ['return', 'exception']:
        val = proc_obj.event_arg
        intf_obj.msg('R=> %s' % proc_obj._saferepr(val))
        pass
    return True
Ejemplo n.º 16
0
    def run(self, args):
        """Get file information"""
        if len(args) == 0:
            if not self.proc.curframe:
                self.errmsg("No frame - no default file.")
                return False
            filename = self.proc.curframe.f_code.co_filename
        else:
            filename = args[0]
            pass

        m = filename + ' is'
        filename_cache = self.core.filename_cache
        if filename in filename_cache:
            m += " cached in debugger"
            if filename_cache[filename] != filename:
                m += ' as:'
                m = Mmisc.wrapped_lines(m, filename_cache[filename] + '.',
                                        self.settings['width'])
            else:
                m += '.'
                pass
            self.msg(m)
        else:
            matches = [
                file for file in self.file_list() if file.endswith(filename)
            ]
            if (len(matches) > 1):
                self.msg("Multiple files found ending filename string:")
                for match_file in matches:
                    self.msg("\t%s" % match_file)
                    pass
            elif len(matches) == 1:
                canonic_name = pyficache.unmap_file(matches[0])
                m += " matched debugger cache file:\n  " + canonic_name
                self.msg(m)
            else:
                self.msg(m + ' not cached in debugger.')
            pass
        canonic_name = self.core.canonic(filename)
        self.msg(
            Mmisc.wrapped_lines('Canonic name:', canonic_name,
                                self.settings['width']))
        for name in (canonic_name, filename):
            if name in sys.modules:
                for key in [
                        k for k, v in list(sys.modules.items()) if name == v
                ]:
                    self.msg("module: %s", key)
                    pass
                pass
            pass
        for arg in args[1:]:
            processed_arg = False
            if arg in ['all', 'size']:
                if pyficache.size(canonic_name):
                    self.msg("File has %d lines." %
                             pyficache.size(canonic_name))
                    pass
                processed_arg = True
                pass
            if arg in ['all', 'sha1']:
                self.msg("SHA1 is %s." % pyficache.sha1(canonic_name))
                processed_arg = True
                pass
            if arg in ['all', 'brkpts']:
                lines = pyficache.trace_line_numbers(canonic_name)
                if lines:
                    self.section("Possible breakpoint line numbers:")
                    fmt_lines = columnize.columnize(lines,
                                                    ljust=False,
                                                    arrange_vertical=False,
                                                    lineprefix='  ')
                    self.msg(fmt_lines)
                    pass
                processed_arg = True
                pass
            if not processed_arg:
                self.errmsg("Don't understand sub-option %s." % arg)
                pass
            pass
        return
Ejemplo n.º 17
0
def print_location(proc_obj):
    """Show where we are. GUI's and front-end interfaces often
    use this to update displays. So it is helpful to make sure
    we give at least some place that's located in a file.
    """
    i_stack = proc_obj.curindex
    if i_stack is None or proc_obj.stack is None:
        return False
    core_obj = proc_obj.core
    dbgr_obj = proc_obj.debugger
    intf_obj = dbgr_obj.intf[-1]

    # Evaluation routines like "exec" don't show useful location
    # info. In these cases, we will use the position before that in
    # the stack.  Hence the looping below which in practices loops
    # once and sometimes twice.
    remapped_file = None
    source_text = None
    while i_stack >= 0:
        frame_lineno = proc_obj.stack[i_stack]
        i_stack -= 1
        frame, lineno = frame_lineno

        #         # Next check to see that local variable breadcrumb exists and
        #         # has the magic dynamic value.
        #         # If so, it's us and we don't normally show this.a
        #         if 'breadcrumb' in frame.f_locals:
        #             if self.run == frame.f_locals['breadcrumb']:
        #                 break

        filename = Mstack.frame2file(core_obj, frame, canonic=False)
        if '<string>' == filename and dbgr_obj.eval_string:
            remapped_file = filename
            filename = pyficache.unmap_file(filename)
            if '<string>' == filename:
                remapped = cmdfns.source_tempfile_remap(
                    'eval_string', dbgr_obj.eval_string)
                pyficache.remap_file(filename, remapped)
                filename = remapped
                lineno = pyficache.unmap_file_line(filename, lineno)
                pass
            pass
        elif '<string>' == filename:
            source_text = deparse_fn(frame.f_code)
            filename = "<string: '%s'>" % source_text
            pass
        else:
            m = re.search('^<frozen (.*)>', filename)
            if m and m.group(1) in pyficache.file2file_remap:
                remapped_file = pyficache.file2file_remap[m.group(1)]
                pass
            elif filename in pyficache.file2file_remap:
                remapped_file = pyficache.unmap_file(filename)
                # FIXME: a remapped_file shouldn't be the same as its unmapped version
                if remapped_file == filename:
                    remapped_file = None
                    pass
                pass
            elif m and m.group(1) in sys.modules:
                remapped_file = m.group(1)
                pyficache.remap_file(filename, remapped_file)
            pass

        opts = {
            'reload_on_change': proc_obj.settings('reload'),
            'output': proc_obj.settings('highlight')
        }

        if 'style' in proc_obj.debugger.settings:
            opts['style'] = proc_obj.settings('style')

        pyficache.update_cache(filename)
        line = pyficache.getline(filename, lineno, opts)
        if not line:
            if (not source_text and filename.startswith("<string: ")
                    and proc_obj.curframe.f_code):
                # Deparse the code object into a temp file and remap the line from code
                # into the corresponding line of the tempfile
                co = proc_obj.curframe.f_code
                temp_filename, name_for_code = deparse_and_cache(
                    co, proc_obj.errmsg)
                lineno = 1
                # _, lineno = pyficache.unmap_file_line(temp_filename, lineno, True)
                if temp_filename:
                    filename = temp_filename
                pass

            else:
                # FIXME:
                if source_text:
                    lines = source_text.split("\n")
                    temp_name = 'string-'
                else:
                    # try with good ol linecache and consider fixing pyficache
                    lines = linecache.getlines(filename)
                    temp_name = filename
                if lines:
                    # FIXME: DRY code with version in cmdproc.py print_location
                    prefix = os.path.basename(temp_name).split('.')[0]
                    fd = tempfile.NamedTemporaryFile(suffix='.py',
                                                     prefix=prefix,
                                                     delete=False)
                    with fd:
                        fd.write(''.join(lines))
                        remapped_file = fd.name
                        pyficache.remap_file(remapped_file, filename)
                    fd.close()
                    pass
            line = linecache.getline(filename, lineno,
                                     proc_obj.curframe.f_globals)
            if not line:
                m = re.search('^<frozen (.*)>', filename)
                if m and m.group(1):
                    remapped_file = m.group(1)
                    try_module = sys.modules.get(remapped_file)
                    if (try_module and inspect.ismodule(try_module)
                            and hasattr(try_module, '__file__')):
                        remapped_file = sys.modules[remapped_file].__file__
                        pyficache.remap_file(filename, remapped_file)
                        line = linecache.getline(remapped_file, lineno,
                                                 proc_obj.curframe.f_globals)
                    else:
                        remapped_file = m.group(1)
                        code = proc_obj.curframe.f_code
                        filename, line = cmdfns.deparse_getline(
                            code, remapped_file, lineno, opts)
                    pass
            pass

        try:
            match, reason = Mstack.check_path_with_frame(frame, filename)
            if not match:
                if filename not in warned_file_mismatches:
                    proc_obj.errmsg(reason)
                    warned_file_mismatches.add(filename)
        except:
            pass

        fn_name = frame.f_code.co_name
        last_i = frame.f_lasti
        print_source_location_info(intf_obj.msg,
                                   filename,
                                   lineno,
                                   fn_name,
                                   remapped_file=remapped_file,
                                   f_lasti=last_i)
        if line and len(line.strip()) != 0:
            if proc_obj.event:
                print_source_line(intf_obj.msg, lineno, line,
                                  proc_obj.event2short[proc_obj.event])
            pass
        if '<string>' != filename: break
        pass

    if proc_obj.event in ['return', 'exception']:
        val = proc_obj.event_arg
        intf_obj.msg('R=> %s' % proc_obj._saferepr(val))
        pass
    return True
Ejemplo n.º 18
0
    def run(self, args):
        proc = self.proc
        dbg_obj  = self.core.debugger
        listsize = dbg_obj.settings['listsize']
        filename, first, last = parse_list_cmd(proc, args, listsize)
        curframe = proc.curframe

        if filename is None: return

        # Sometimes such as due to decompilation we might not really
        # have an idea based on the listing where we really are.
        # Setting "show_marks" to false will disable marking breakpoint
        # and current line numbers.
        show_marks = True

        filename = pyficache.unmap_file(pyficache.pyc2py(filename))

        if filename == "<string>" and proc.curframe.f_code:
            # Deparse the code object into a temp file and remap the line from code
            # into the corresponding line of the tempfile
            co = proc.curframe.f_code
            temp_filename, name_for_code = deparse_and_cache(co, proc.errmsg)
            if temp_filename:
                filename = temp_filename
                show_marks = False
            pass

        # We now have range information. Do the listing.
        max_line = pyficache.size(filename)
        if max_line is None:
            self.errmsg('No file %s found; using "deparse" command instead to show source' %
                        filename)
            proc.commands['deparse'].run(['deparse'])
            return

        canonic_filename = os.path.realpath(os.path.normcase(filename))

        if first > max_line:
            self.errmsg('Bad start line %d - file "%s" has only %d lines'
                        % (first, filename, max_line))
            return

        if last > max_line:
            self.msg('End position changed to last line %d ' % max_line)
            last = max_line

        bplist = self.core.bpmgr.bplist
        opts = {
            'reload_on_change' : self.settings['reload'],
            'output'           : self.settings['highlight'],
            'strip_nl'         : False,
            }

        if 'style' in self.settings:
            opts['style'] = self.settings['style']

        if first <= 0:
            first = 1
        try:
            for lineno in range(first, last+1):
                line = pyficache.getline(filename, lineno, opts)
                if line is None:
                    line = linecache.getline(filename, lineno,
                                             proc.frame.f_globals)
                    pass
                if line is None:
                    self.msg('[EOF]')
                    break
                else:
                    line = line.rstrip('\n')
                    s = proc._saferepr(lineno).rjust(3)
                    if len(s) < 5: s += ' '
                    if (show_marks and
                        (canonic_filename, lineno,) in list(bplist.keys())):
                        bp    = bplist[(canonic_filename, lineno,)][0]
                        a_pad = '%02d' % bp.number
                        s    += bp.icon_char()
                    else:
                        s    += ' '
                        a_pad = '  '
                        pass
                    if (curframe and lineno == inspect.getlineno(curframe)
                        and show_marks):
                        s += '->'
                        if 'plain' != self.settings['highlight']:
                            s = colorize('bold', s)
                    else:
                        s += a_pad
                        pass
                    self.msg(s + '\t' + line)
                    proc.list_lineno = lineno
                    pass
                pass
            pass
        except KeyboardInterrupt:
            pass
        return False
Ejemplo n.º 19
0
    def run(self, args):
        proc = self.proc
        dbg_obj = self.core.debugger
        listsize = dbg_obj.settings['listsize']
        filename, first, last = parse_list_cmd(proc, args, listsize)
        curframe = proc.curframe
        if filename is None: return
        filename = pyficache.unmap_file(pyficache.pyc2py(filename))

        # We now have range information. Do the listing.
        max_line = pyficache.size(filename)
        if max_line is None:
            self.errmsg(
                'No file %s found; using "deparse" command instead to show source'
                % filename)
            proc.commands['deparse'].run(['deparse'])
            return

        canonic_filename = os.path.realpath(os.path.normcase(filename))

        if first > max_line:
            self.errmsg('Bad start line %d - file "%s" has only %d lines' %
                        (first, filename, max_line))
            return

        if last > max_line:
            self.msg('End position changed to last line %d ' % max_line)
            last = max_line

        bplist = self.core.bpmgr.bplist
        opts = {
            'reload_on_change': self.settings['reload'],
            'output': self.settings['highlight'],
            'strip_nl': False,
        }

        if 'style' in self.settings:
            opts['style'] = self.settings['style']

        if first <= 0:
            first = 1
        try:
            for lineno in range(first, last + 1):
                line = pyficache.getline(filename, lineno, opts)
                if line is None:
                    line = linecache.getline(filename, lineno,
                                             proc.frame.f_globals)
                    pass
                if line is None:
                    self.msg('[EOF]')
                    break
                else:
                    line = line.rstrip('\n')
                    s = proc._saferepr(lineno).rjust(3)
                    if len(s) < 5: s += ' '
                    if (
                            canonic_filename,
                            lineno,
                    ) in list(bplist.keys()):
                        bp = bplist[(
                            canonic_filename,
                            lineno,
                        )][0]
                        a_pad = '%02d' % bp.number
                        s += bp.icon_char()
                    else:
                        s += ' '
                        a_pad = '  '
                        pass
                    if curframe and lineno == inspect.getlineno(curframe):
                        s += '->'
                        if 'plain' != self.settings['highlight']:
                            s = colorize('bold', s)
                    else:
                        s += a_pad
                        pass
                    self.msg(s + '\t' + line)
                    proc.list_lineno = lineno
                    pass
                pass
            pass
        except KeyboardInterrupt:
            pass
        return False
Ejemplo n.º 20
0
def print_location(proc_obj):
    """Show where we are. GUI's and front-end interfaces often
    use this to update displays. So it is helpful to make sure
    we give at least some place that's located in a file.
    """
    i_stack = proc_obj.curindex
    if i_stack is None or proc_obj.stack is None:
        return False
    core_obj = proc_obj.core
    dbgr_obj = proc_obj.debugger
    intf_obj = dbgr_obj.intf[-1]

    # Evaluation routines like "exec" don't show useful location
    # info. In these cases, we will use the position before that in
    # the stack.  Hence the looping below which in practices loops
    # once and sometimes twice.
    remapped_file = None
    while i_stack >= 0:
        frame_lineno = proc_obj.stack[i_stack]
        i_stack -= 1
        frame, lineno = frame_lineno

        #         # Next check to see that local variable breadcrumb exists and
        #         # has the magic dynamic value.
        #         # If so, it's us and we don't normally show this.a
        #         if 'breadcrumb' in frame.f_locals:
        #             if self.run == frame.f_locals['breadcrumb']:
        #                 break

        filename = Mstack.frame2file(core_obj, frame, canonic=False)
        if '<string>' == filename and dbgr_obj.eval_string:
            remapped_file = filename
            filename = pyficache.unmap_file(filename)
            if '<string>' == filename:
                fd = tempfile.NamedTemporaryFile(suffix='.py',
                                                 prefix='eval_string',
                                                 delete=False)
                with fd:
                    fd.write(dbgr_obj.eval_string)
                    fd.close()
                    pass
                pyficache.remap_file(fd.name, '<string>')
                filename = fd.name
                pass
            pass
        else:
            if filename in pyficache.file2file_remap:
                remapped_file = pyficache.unmap_file(filename)
                # FIXME: a remapped_file shouldn't be the same as its unmapped version
                if remapped_file == filename:
                    remapped_file = None
                    pass
                pass
            pass

        opts = {
            'reload_on_change': proc_obj.settings('reload'),
            'output': proc_obj.settings('highlight')
        }

        if 'style' in proc_obj.debugger.settings:
            opts['style'] = proc_obj.settings('style')

        pyficache.update_cache(filename)
        line = pyficache.getline(filename, lineno, opts)
        if not line:
            # FIXME:
            # try with good ol linecache and consider fixing pyficache
            lines = linecache.getlines(filename)
            if lines:
                # FIXME: DRY code with version in cmdproc.py print_location
                prefix = os.path.basename(filename).split('.')[0]
                fd = tempfile.NamedTemporaryFile(suffix='.py',
                                                 prefix=prefix,
                                                 delete=False)
                with fd:
                    fd.write(''.join(lines))
                    remapped_file = fd.name
                    pyficache.remap_file(remapped_file, filename)
                fd.close()
                pass
            line = linecache.getline(filename, lineno,
                                     proc_obj.curframe.f_globals)
            pass

        fn_name = frame.f_code.co_name
        last_i = frame.f_lasti
        print_source_location_info(intf_obj.msg,
                                   filename,
                                   lineno,
                                   fn_name,
                                   remapped_file=remapped_file,
                                   f_lasti=last_i)
        if line and len(line.strip()) != 0:
            if proc_obj.event:
                print_source_line(intf_obj.msg, lineno, line,
                                  proc_obj.event2short[proc_obj.event])
            pass
        if '<string>' != filename: break
        pass

    if proc_obj.event in ['return', 'exception']:
        val = proc_obj.event_arg
        intf_obj.msg('R=> %s' % proc_obj._saferepr(val))
        pass
    return True
Ejemplo n.º 21
0
def print_location(proc_obj):
    """Show where we are. GUI's and front-end interfaces often
    use this to update displays. So it is helpful to make sure
    we give at least some place that's located in a file.
    """
    i_stack = proc_obj.curindex
    if i_stack is None or proc_obj.stack is None:
        return False
    core_obj = proc_obj.core
    dbgr_obj = proc_obj.debugger
    intf_obj = dbgr_obj.intf[-1]

    # Evaluation routines like "exec" don't show useful location
    # info. In these cases, we will use the position before that in
    # the stack.  Hence the looping below which in practices loops
    # once and sometimes twice.
    remapped_file = None
    while i_stack >= 0:
        frame_lineno = proc_obj.stack[i_stack]
        i_stack -= 1
        frame, lineno = frame_lineno

        #         # Next check to see that local variable breadcrumb exists and
        #         # has the magic dynamic value.
        #         # If so, it's us and we don't normally show this.a
        #         if 'breadcrumb' in frame.f_locals:
        #             if self.run == frame.f_locals['breadcrumb']:
        #                 break

        filename = Mstack.frame2file(core_obj, frame)
        if '<string>' == filename and dbgr_obj.eval_string:
            remapped_file = filename
            filename = pyficache.unmap_file(filename)
            if '<string>' == filename:
                fd = tempfile.NamedTemporaryFile(suffix='.py',
                                                 prefix='eval_string',
                                                 delete=False)
                fd.write(dbgr_obj.eval_string)
                fd.close()
                pyficache.remap_file(fd.name, '<string>')
                filename = fd.name
                pass
            pass

        fn_name = frame.f_code.co_name
        print_source_location_info(intf_obj.msg,
                                   filename,
                                   lineno,
                                   fn_name,
                                   remapped_file=remapped_file)
        # proc_obj.curframe.f_lasti)

        opts = {
            'reload_on_change': proc_obj.settings('reload'),
            'output': proc_obj.settings('highlight')
        }
        line = pyficache.getline(filename, lineno, opts)
        if not line:
            if sys.version_info[1] <= 4:
                # Python 2.4 and before doesn't have 3-arg getline
                line = linecache.getline(filename, lineno)
            else:
                line = linecache.getline(filename, lineno,
                                         proc_obj.curframe.f_globals)
                pass
            pass

        if line and len(line.strip()) != 0:
            if proc_obj.event:
                print_source_line(intf_obj.msg, lineno, line,
                                  proc_obj.event2short[proc_obj.event])
            pass
        if '<string>' != filename: break
        pass

    if proc_obj.event in ['return', 'exception']:
        val = proc_obj.event_arg
        intf_obj.msg('R=> %s' % proc_obj._saferepr(val))
        pass
    return True