def run_list(self, args): # Check if there is a "file" to show. Right now we just # handle the case of a string. # FIXME: generalize this so for other kinds of missing "files" # are not shown. filename = Mstack.frame2file(self.core, self.proc.curframe) if '<string>' != filename: self.list_cmd(['list']) return
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. 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: 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
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. 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: 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 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
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
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
def resolve_location(proc, location, canonic=True): """Expand fields in Location namedtuple. If: '.': get fields from stack function/module: get fields from evaluation/introspection location file and line number: use that """ curframe = proc.curframe if location == '.': if not curframe: proc.errmsg("Don't have a stack to get location from") return INVALID_LOCATION filename = Mstack.frame2file(proc.core, curframe, canonic=canonic) lineno = inspect.getlineno(curframe) return Location(filename, lineno, False, None) assert isinstance(location, Location) is_address = False if proc.curframe: g = curframe.f_globals l = curframe.f_locals else: g = globals() l = locals() pass if location.method: # Validate arguments that can't be done in parsing filename = lineno = None msg = ('Object %s is not known yet as a function, ' % location.method) try: modfunc = eval(location.method, g, l) except: proc.errmsg(msg) return INVALID_LOCATION try: # Check if the converted string is a function or instance method if inspect.isfunction(modfunc) or hasattr(modfunc, 'im_func'): pass else: proc.errmsg(msg) return INVALID_LOCATION except: proc.errmsg(msg) return INVALID_LOCATION filename = proc.core.canonic(modfunc.func_code.co_filename) # FIXME: we may want to check lineno and # respect that in the future lineno = modfunc.func_code.co_firstlineno elif location.path: filename = proc.core.canonic(location.path) lineno = location.line_number modfunc = None msg = "%s is not known as a file" % location.path if not osp.isfile(filename): # See if argument is a module try: modfunc = eval(location.path, g, l) except: msg = ("Don't see '%s' as a existing file or as an module" % location.path) proc.errmsg(msg) return INVALID_LOCATION pass is_address = location.is_address if inspect.ismodule(modfunc): if hasattr(modfunc, '__file__'): filename = pyficache.pyc2py(modfunc.__file__) filename = proc.core.canonic(filename) if not lineno: # use first line of module file lineno = 1 is_address = False return Location(filename, lineno, is_address, modfunc) else: msg = ("module '%s' doesn't have a file associated with it" % location.path) proc.errmsg(msg) return INVALID_LOCATION maxline = pyficache.maxline(filename) if maxline and lineno > maxline: # NB: we use the gdb wording here proc.errmsg("Line number %d out of range; %s has %d lines." % (lineno, filename, maxline)) return INVALID_LOCATION elif location.line_number: filename = Mstack.frame2file(proc.core, curframe, canonic=canonic) lineno = location.line_number is_address = location.is_address modfunc = None return Location(filename, lineno, is_address, modfunc)
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
def resolve_location(proc, location): """Expand fields in Location namedtuple. If: '.': get fields from stack function/module: get fields from evaluation/introspection location file and line number: use that """ curframe = proc.curframe offset = None if location == ".": if not curframe: proc.errmsg("Don't have a stack to get location from") return INVALID_LOCATION filename = frame2file(proc.core, curframe, canonic=False) lineno = inspect.getlineno(curframe) offset = curframe.f_lasti return Location(filename, lineno, False, None, offset) assert isinstance(location, Location) is_address = location.is_address if proc.curframe: g = curframe.f_globals l = curframe.f_locals else: g = globals() l = locals() pass if location.method: # Validate arguments that can't be done in parsing filename = lineno = None msg = "Object %s is not known yet as a function, " % location.method try: modfunc = eval(location.method, g, l) except: proc.errmsg(msg) return INVALID_LOCATION try: # Check if the converted string is a function or instance # method. We don't want to test on attributes and not use # `inspect.isfunction()` so that we can accomadate # trepan-xpy() which has it's own type of compatible # Function, that would fail an `inspect.isfunction()` # test. if hasattr(modfunc, "__code__") or hasattr(modfunc, "im_func"): offset = -1 else: proc.errmsg(msg) return INVALID_LOCATION except: proc.errmsg(msg) return INVALID_LOCATION filename = proc.core.canonic(modfunc.__code__.co_filename) # FIXME: we may want to check lineno and # respect that in the future lineno = modfunc.__code__.co_firstlineno elif location.path: filename = proc.core.canonic(location.path) lineno = location.line_number modfunc = None msg = "%s is not known as a file" % location.path if not osp.isfile(filename): # See if argument is a module try: modfunc = eval(location.path, g, l) except: msg = ("Don't see '%s' as a existing file or as an module" % location.path) proc.errmsg(msg) return INVALID_LOCATION pass is_address = location.is_address if inspect.ismodule(modfunc): if hasattr(modfunc, "__file__"): filename = pyficache.resolve_name_to_path(modfunc.__file__) filename = proc.core.canonic(filename) if not lineno: # use first line of module file lineno = 1 offset = 0 is_address = False return Location(filename, lineno, is_address, modfunc, offset) else: msg = ( "module '%s' doesn't have a file associated with it" % location.path) proc.errmsg(msg) return INVALID_LOCATION maxline = pyficache.maxline(filename) if maxline and lineno > maxline: # NB: we use the gdb wording here proc.errmsg("Line number %d out of range; %s has %d lines." % (lineno, filename, maxline)) return INVALID_LOCATION offset = location.offset if offset is None: lineinfo = pyficache.code_line_info(filename, lineno) if lineinfo: offset = lineinfo[0].offsets[0] modfunc = lineinfo[0].name else: print("No offset found for %s %s" % (filename, lineno)) elif location.line_number: filename = frame2file(proc.core, curframe, canonic=False) lineno = location.line_number is_address = location.is_address modfunc = None if offset is None: lineinfo = pyficache.code_line_info(filename, lineno, include_offsets=True) if lineinfo: offset = lineinfo[0].offsets[0] modfunc = lineinfo[0].name elif location.offset is not None: filename = frame2file(proc.core, curframe, canonic=False) is_address = True lineno = None modfunc = None offset = location.offset return Location(filename, lineno, is_address, modfunc, offset)
def resolve_address_location(proc, location): """Expand fields in Location namedtuple. If: '.': get fields from stack function/module: get fields from evaluation/introspection location file and line number: use that """ curframe = proc.curframe if location == ".": filename = frame2file(proc.core, curframe, canonic=False) offset = curframe.f_lasti is_address = True return Location(filename, offset, False, None, offset) assert isinstance(location, Location) is_address = True if proc.curframe: g = curframe.f_globals l = curframe.f_locals else: g = globals() l = locals() pass if location.method: # Validate arguments that can't be done in parsing filename = offset = None msg = "Object %s is not known yet as a function, " % location.method try: modfunc = eval(location.method, g, l) except: proc.errmsg(msg) return INVALID_LOCATION try: # Check if the converted string is a function or instance method if inspect.isfunction(modfunc) or hasattr(modfunc, "im_func"): pass else: proc.errmsg(msg) return INVALID_LOCATION except: proc.errmsg(msg) return INVALID_LOCATION filename = proc.core.canonic(modfunc.func_code.co_filename) # FIXME: we may want to check offset and # respect that in the future offset = 0 elif location.path: filename = proc.core.canonic(location.path) offset = location.line_number is_address = location.is_address modfunc = None msg = "%s is not known as a file" % location.path if not osp.isfile(filename): # See if argument is a module try: modfunc = eval(location.path, g, l) except: msg = ("Don't see '%s' as a existing file or as an module" % location.path) proc.errmsg(msg) return INVALID_LOCATION pass is_address = location.is_address if inspect.ismodule(modfunc): if hasattr(modfunc, "__file__"): filename = pyficache.resolve_name_to_path(modfunc.__file__) filename = proc.core.canonic(filename) if not offset: # use first offset of module file offset = 0 is_address = True return Location(filename, offset, is_address, modfunc, offset) else: msg = ( "module '%s' doesn't have a file associated with it" % location.path) proc.errmsg(msg) return INVALID_LOCATION maxline = pyficache.maxline(filename) if maxline and offset > maxline: # NB: we use the gdb wording here proc.errmsg("Line number %d out of range; %s has %d lines." % (offset, filename, maxline)) return INVALID_LOCATION elif location.line_number is not None: filename = frame2file(proc.core, curframe, canonic=False) offset = location.line_number is_address = location.is_address modfunc = proc.list_object else: proc.errmsg( f"Location {location} doesn't have enough information for a location." ) return INVALID_LOCATION return Location(filename, offset, is_address, modfunc, offset)
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
def resolve_location(proc, location): """Expand fields in Location namedtuple. If: '.': get fields from stack function/module: get fields from evaluation/introspection location file and line number: use that """ curframe = proc.curframe if location == '.': if not curframe: proc.errmsg("Don't have a stack to get location from") return INVALID_LOCATION filename = Mstack.frame2file(proc.core, curframe, canonic=False) lineno = inspect.getlineno(curframe) return Location(filename, lineno, False, None) assert isinstance(location, Location) is_address = False if proc.curframe: g = curframe.f_globals l = curframe.f_locals else: g = globals() l = locals() pass if location.method: # Validate arguments that can't be done in parsing filename = lineno = None msg = ('Object %s is not known yet as a function, ' % location.method) try: modfunc = eval(location.method, g, l) except: proc.errmsg(msg) return INVALID_LOCATION try: # Check if the converted string is a function or instance method if inspect.isfunction(modfunc) or hasattr(modfunc, 'im_func'): pass else: proc.errmsg(msg) return INVALID_LOCATION except: proc.errmsg(msg) return INVALID_LOCATION filename = proc.core.canonic(modfunc.__code__.co_filename) # FIXME: we may want to check lineno and # respect that in the future lineno = modfunc.__code__.co_firstlineno elif location.path: filename = proc.core.canonic(location.path) lineno = location.line_number modfunc = None msg = "%s is not known as a file" % location.path if not osp.isfile(filename): # See if argument is a module try: modfunc = eval(location.path, g, l) except: msg = ("Don't see '%s' as a existing file or as an module" % location.path) proc.errmsg(msg) return INVALID_LOCATION pass is_address = location.is_address if inspect.ismodule(modfunc): if hasattr(modfunc, '__file__'): filename = pyficache.pyc2py(modfunc.__file__) filename = proc.core.canonic(filename) if not lineno: # use first line of module file lineno = 1 is_address = False return Location(filename, lineno, is_address, modfunc) else: msg = ( "module '%s' doesn't have a file associated with it" % location.path) proc.errmsg(msg) return INVALID_LOCATION maxline = pyficache.maxline(filename) if maxline and lineno > maxline: # NB: we use the gdb wording here proc.errmsg("Line number %d out of range; %s has %d lines." % (lineno, filename, maxline)) return INVALID_LOCATION elif location.line_number: filename = Mstack.frame2file(proc.core, curframe, canonic=False) lineno = location.line_number is_address = location.is_address modfunc = None return Location(filename, lineno, is_address, modfunc)
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