def deparse_and_cache(co): # co = proc_obj.curframe.f_code out = StringIO() try: deparsed = deparse_code_with_map(co, out) except: return None, None text = out.getvalue() linemap = [(line_no, deparsed.source_linemap[line_no]) for line_no in sorted(deparsed.source_linemap.keys())] # FIXME: DRY code with version in cmdproc.py print_location name_for_code = sha1(co.co_code).hexdigest()[:6] prefix = "deparsed-" fd = tempfile.NamedTemporaryFile(suffix=".py", prefix=prefix, delete=False) with fd: fd.write(text.encode("utf-8")) map_line = "\n\n# %s" % linemap fd.write(map_line.encode("utf-8")) remapped_file = fd.name fd.close() # FIXME remap filename to a short name. pyficache.remap_file_lines(name_for_code, remapped_file, linemap) return remapped_file, name_for_code
def deparse_and_cache(co, errmsg_fn): # co = proc_obj.curframe.f_code out = StringIO() deparsed = deparse_cache.get(co, None) if not deparsed or not hasattr(deparsed, "source_linemap"): try: deparsed = code_deparse_with_map(co, out) except: errmsg_fn(str(sys.exc_info()[0])) errmsg_fn("error in deparsing code: %s" % co.co_filename) return None, None deparse_cache[co] = deparsed text = out.getvalue() linemap = [(line_no, deparsed.source_linemap[line_no]) for line_no in sorted(deparsed.source_linemap.keys())] # FIXME: DRY code with version in cmdproc.py print_location name_for_code = sha1(co.co_code).hexdigest()[:6] prefix = 'deparsed-' fd = tempfile.NamedTemporaryFile(suffix='.py', prefix=prefix) fd.write(text.encode('utf-8')) map_line = "\n\n# %s" % linemap fd.write(map_line.encode('utf-8')) remapped_file = fd.name # FIXME remap filename to a short name. pyficache.remap_file_lines(name_for_code, remapped_file, linemap) return remapped_file, name_for_code
def deparse_getline(code, filename, line_number, opts): # Would love to figure out how to deparse the entire module # but with all many-time rewritten import stuff, I still # can't figure out how to get from "<frozen importlib>" to # the module's code. # So for now, we'll have to do this on a function by function # bases. Fortunately pyficache has the ability to remap line # numbers text = deparse_fn(code) if text: prefix = os.path.basename(filename) + "_" remapped_filename = source_tempfile_remap(prefix, text) lines = text.split("\n") first_line = code.co_firstlineno pyficache.remap_file_lines(filename, remapped_filename, range(first_line, first_line + len(lines)), 1) return remapped_filename, pyficache.getline(filename, line_number, opts) return None, None
def deparse_getline(code, filename, line_number, opts): # Would love to figure out how to deparse the entire module # but with all many-time rewritten import stuff, I still # can't figure out how to get from "<frozen importlib>" to # the module's code. # So for now, we'll have to do this on a function by function # bases. Fortunately pyficache has the ability to remap line # numbers text = deparse_fn(code) if text: prefix = os.path.basename(filename) + "_" remapped_filename = source_tempfile_remap(prefix, text) lines = text.split("\n") first_line = code.co_firstlineno pyficache.remap_file_lines(filename, remapped_filename, range(first_line, first_line+len(lines)), 1) return remapped_filename, pyficache.getline(filename, line_number, opts) return None, None
def test_remap_lines(self): pyficache.remap_file_lines(__file__, 'test2', list(range(10, 12)), 6) line5 = pyficache.getline(__file__, 5) pyficache.remap_file_lines(__file__, 'test2', 9, 5) rline9 = pyficache.getline('test2', 9) self.assertEqual( line5, rline9, 'lines should be the same via remap_file_line - ' 'remap integer') line6 = pyficache.getline(__file__, 6) rline10 = pyficache.getline('test2', 10) self.assertEqual( line6, rline10, 'lines should be the same via remap_file_line - ' 'range') line7 = pyficache.getline(__file__, 7) rline11 = pyficache.getline('test2', 11) self.assertEqual( line7, rline11, 'lines should be the same via remap_file_line - ' 'range') line8 = pyficache.getline(__file__, 8) pyficache.remap_file_lines(__file__, None, 20, 8) rline20 = pyficache.getline(__file__, 20) self.assertEqual( line8, rline20, 'lines should be the same via remap_file_line - ' 'None file') return
def deparse_getline(code, filename, line_number, opts): # I Would like to figure out how to deparse the entire module, # instead doing this on a line-by-line basis. # But because th Python import library routines have been rewritten many times, I # can't figure out how to get from "<frozen importlib>" to # the module's code. # So for now, we'll have to do this on a function by function # bases. Fortunately pyficache has the ability to remap line # numbers deparsed = deparse_fn(code) text = deparsed.text.strip() if text: prefix = os.path.basename(filename) + "_" remapped_filename = source_tempfile_remap(prefix, text) lines = text.split("\n") first_line = code.co_firstlineno linemap = [(line_no, deparsed.source_linemap[line_no]) for line_no in sorted(deparsed.source_linemap.keys())] print("XXXX", linemap) pyficache.remap_file_lines(filename, remapped_filename, linemap) return remapped_filename, pyficache.getline(filename, line_number, opts) return None, None