def _extract_tokens_from_stack(self): """Load file of stack and get the relevant tokens from statement""" # Get the source of the last stack source = Source(self.last_stack.filename, linecache.getlines(self.last_stack.filename)) # Extract all relevant parts tokens = extrace_statement_from_source(source, self.last_stack) return tokens
def check_skipping_frames(collapse: bool): def factorial(n): if n <= 1: return 1 / 0 # exception lineno return n * foo(n - 1) # factorial lineno def foo(n): return factorial(n) # foo lineno try: factorial(20) # check_skipping_frames lineno except Exception as e: # tb = sys.exc_info()[2] tb = e.__traceback__ result = [] for x in FrameInfo.stack_data(tb, collapse_repeated_frames=collapse): if isinstance(x, FrameInfo): result.append((x.code, x.lineno)) else: result.append(repr(x)) source = Source.for_filename(__file__) linenos = {} for lineno, line in enumerate(source.lines): match = re.search(r" # (\w+) lineno", line) if match: linenos[match.group(1)] = lineno + 1 def simple_frame(func): return func.__code__, linenos[func.__name__] if collapse: middle = [ simple_frame(factorial), simple_frame(foo), simple_frame(factorial), simple_frame(foo), ("<RepeatedFrames " "check_skipping_frames.<locals>.factorial at line {factorial} (16 times), " "check_skipping_frames.<locals>.foo at line {foo} (16 times)>" ).format(**linenos), simple_frame(factorial), simple_frame(foo), ] else: middle = [*([ simple_frame(factorial), simple_frame(foo), ] * 19)] assert result == [ simple_frame(check_skipping_frames), *middle, (factorial.__code__, linenos["exception"]), ]
def test_absolute_filename(): sys.path.append(str(samples_dir)) short_filename = "to_exec.py" full_filename = str(samples_dir / short_filename) source = Source.for_filename(short_filename) names = {} code = compile(source.text, short_filename, "exec") exec(code, names) frame_info = names["frame_info"] assert frame_info.source is source assert frame_info.code is code assert code.co_filename == source.filename == short_filename assert frame_info.filename == full_filename
def sys_modules_sources(): for module in sys.modules.values(): try: filename = inspect.getsourcefile(module) except TypeError: continue if not filename: continue filename = os.path.abspath(filename) print(filename) source = Source.for_filename(filename) if not source.tree: continue yield source
def test_pieces(): filename = samples_dir / "pieces.py" source = Source.for_filename(str(filename)) pieces = [[source.lines[i - 1] for i in piece] for piece in source.pieces] assert pieces == [ ['import math'], ['def foo(x=1, y=2):'], [' """', ' a docstring', ' """'], [' z = 0'], [' for i in range(5):'], [' z += i * x * math.sin(y)'], [' # comment1', ' # comment2'], [ ' z += math.copysign(', ' -1,', ' 2,', ' )' ], [' for i in range(', ' 0,', ' 6', ' ):'], [' try:'], [' str(i)'], [' except:'], [' pass'], [' try:'], [' int(i)'], [' except (ValueError,', ' TypeError):'], [' pass'], [' finally:'], [' str("""', ' foo', ' """)'], [' str(f"""', ' {str(str)}', ' """)'], [ ' str(f"""', ' foo', ' {', ' str(', ' str', ' )', ' }', ' bar', ' {str(str)}', ' baz', ' {', ' str(', ' str', ' )', ' }', ' spam', ' """)' ], ['def foo2(', ' x=1,', ' y=2,', '):'], [' while 9:'], [' while (', ' 9 + 9', ' ):'], [' if 1:'], [' pass'], [' elif 2:'], [' pass'], [' elif (', ' 3 + 3', ' ):'], [' pass'], [' else:'], [' pass'], ['class Foo(object):'], [' @property', ' def foo(self):'], [' return 3'] ]
def test_invalid_source(): filename = str(samples_dir / "not_code.txt") source = Source.for_filename(filename) assert not source.tree assert not hasattr(source, "tokens_by_lineno")
from pathlib import Path from stack_data import Source from stack_data.test_utils import print_pieces, print_lines filename = str(Path(__file__).parent / "stack_data/core.py") source = Source.for_filename(filename) print_pieces(source) def bar(): def foo(): x = 1 lst = [1, 2, 3, 4, 5, 6] lst.insert(0, x) lst.append(x) lst.append([9, 99][0]) print_lines() return lst foo() bar()