def test_mutable(): code = """\ a = [1, 2, [3, 4]] a[0] = 9 a[2][1] = 8 b = a i, j = 2, 1 a[i][j] = 7 a[0:2] = list(reversed(a[0:2])) b = a d = -1 a[i:j:d] = [100] b = a """ expected_report = """\ a = [1, 2, [3, 4]] a[0] = 9 a[2][1] = 8 b = [9, 2, [3, 8]] (i, j) = (2, 1) a[2][1] = 7 a[0:2] = [2, 9] b = [2, 9, [3, 7]] d = -1 a[2:1:-1] = [100] b = [2, 9, 100] """ report = TraceRunner().trace_code(code) assert trim_report(expected_report) == trim_report(report)
def test_slice(): code = """\ a = [1, 2, 3, 4, 5] i, j = 1, 4 a[i:j] = [20, 30] b = a a[2:] = [300] b = a a[:2] *= 2 b = a a[:2] += [21] b = a """ expected_report = """\ a = [1, 2, 3, 4, 5] (i, j) = (1, 4) a[1:4] = [20, 30] b = [1, 20, 30, 5] a[2:] = [300] b = [1, 20, 300] a[:2] *= 2 b = [1, 20, 1, 20, 300] a[:2] += [21] b = [1, 20, 21, 1, 20, 300] """ report = CodeTracer().trace_code(code) assert trim_report(expected_report) == trim_report(report)
def test_slice(): code = """\ a = [1, 2, 3, 4, 5] i, j = 1, 4 a[i:j] = [20, 30] b = a a[2:] = [300] b = a a[:2] *= 2 b = a a[:2] += [21] b = a """ expected_report = """\ a = [1, 2, 3, 4, 5] (i, j) = (1, 4) a[1:4] = [20, 30] b = [1, 20, 30, 5] a[2:] = [300] b = [1, 20, 300] a[:2] *= 2 b = [1, 20, 1, 20, 300] a[:2] += [21] b = [1, 20, 21, 1, 20, 300] """ report = TraceRunner().trace_code(code) assert trim_report(expected_report) == trim_report(report)
def test_mutable(): code = """\ a = [1, 2, [3, 4]] a[0] = 9 a[2][1] = 8 b = a i, j = 2, 1 a[i][j] = 7 a[0:2] = list(reversed(a[0:2])) b = a d = -1 a[i:j:d] = [100] b = a """ expected_report = """\ a = [1, 2, [3, 4]] a[0] = 9 a[2][1] = 8 b = [9, 2, [3, 8]] (i, j) = (2, 1) a[2][1] = 7 a[0:2] = [2, 9] b = [2, 9, [3, 7]] d = -1 a[2:1:-1] = [100] b = [2, 9, 100] """ report = CodeTracer().trace_code(code) assert trim_report(expected_report) == trim_report(report)
def test_repr_lambda(): code = """\ class Foo: def __init__(self, x): self.x = x def __repr__(self): return 'Foo({!r})'.format(self.x) y = list(map(lambda n: Foo(n), range(2))) """ expected_report = """\ x = 0 | x = 1 self.x = 0 | self.x = 1 (0 => Foo(0)) | (1 => Foo(1)) | y = [Foo(0), Foo(1)] """ tracer = TraceRunner() report = tracer.trace_code(code) assert trim_report(expected_report) == trim_report(report)
def test_repr_yield_tuple(): code = """\ class Foo: def __init__(self, x): self.x = x def __repr__(self): return 'Foo({!r})'.format(self.x) def bar(x): yield x, Foo(x) y = list(bar(23)) """ expected_report = """\ x = 23 self.x = 23 x = 23 yield (23, Foo(23)) y = [(23, Foo(23))] """ tracer = TraceRunner() report = tracer.trace_code(code) assert trim_report(expected_report) == trim_report(report)
def test_error(): code = """\ from __future__ import print_function class Foo(object): def __repr__(self): raise RuntimeError('Bad representation.') def create_foo(): return Foo() print('Start.') foo = create_foo() print('End.') """ expected_report = """\ return <Foo object> print('Start.') print('End.') """ tracer = TraceRunner() report = tracer.trace_code(code) assert trim_report(expected_report) == trim_report(report)
def test_repr_call(): code = """\ class Dog(object): def __init__(self, name): self.name = name def __repr__(self): return 'Dog(%r)' % self.name dog1 = Dog('Spot') dog2 = Dog('Fido') s = repr(dog2) """ expected_report = """\ name = 'Spot' | name = 'Fido' self.name = 'Spot' | self.name = 'Fido' return "Dog('Fido')" dog1 = Dog('Spot') dog2 = Dog('Fido') s = "Dog('Fido')" """ tracer = TraceRunner() report = tracer.trace_code(code) assert trim_report(expected_report) == trim_report(report)
def test_repr_return(): code = """\ class Foo: def __init__(self, x): self.x = x def __repr__(self): return 'Foo({!r})'.format(self.x) def bar(x): return Foo(x) y = bar(23) """ expected_report = """\ x = 23 self.x = 23 x = 23 return Foo(23) y = Foo(23) """ tracer = TraceRunner() report = tracer.trace_code(code) assert trim_report(expected_report) == trim_report(report)
def test_repr(): code = """\ class Dog(object): def __init__(self, name): self.name = name def __repr__(self): return 'Dog(%r)' % self.name dog = Dog('Spot') animal = dog """ expected_report = """\ name = 'Spot' self.name = 'Spot' dog = Dog('Spot') animal = Dog('Spot') """ tracer = TraceRunner() report = tracer.trace_code(code) assert trim_report(expected_report) == trim_report(report)
def test_traced_renamed(): code = """\ from space_tracer import traced as space_traced @space_traced def foo(n): s = 'x' for i in range(n): s += 'y' return s print(foo(3)) """ expected_report = """\ @space_traced | def foo(n): | n = 3 s = 'x' | s = 'x' for i in range(n): | i = 0 | i = 1 | i = 2 s += 'y' | s = 'xy' | s = 'xyy' | s = 'xyyy' return s | return 'xyyy' """ with replace_input(code): report = TraceRunner().trace_command([ 'space_tracer', '--source_indent', '4', '--traced_file', 'example.py', 'example.py' ]) assert trim_report(expected_report) == trim_report(report)
def test_slice_magic(): """ All augmented assignments on slices, possible with mocks. """ code = """\ from unittest.mock import MagicMock class Foo(MagicMock): def __repr__(self): return 'Foo()' foo = Foo() foo[1] = 3 foo[1:10] = 3 foo[1:10:2] = 3 foo[...] = 3 foo[1, 2:3] = 3 foo[1:10] += 3 foo[1:10] -= 3 foo[1:10] *= 3 foo[1:10] /= 3 foo[1:10] //= 3 foo[1:10] %= 3 foo[1:10] **= 3 foo[1:10] >>= 3 foo[1:10] <<= 3 foo[1:10] &= 3 foo[1:10] ^= 3 foo[1:10] |= 3 """ expected_report = """\ foo = Foo() foo[1] = 3 foo[1:10] = 3 foo[1:10:2] = 3 foo[...] = 3 foo[1, 2:3] = 3 foo[1:10] += 3 foo[1:10] -= 3 foo[1:10] *= 3 foo[1:10] /= 3 foo[1:10] //= 3 foo[1:10] %= 3 foo[1:10] **= 3 foo[1:10] >>= 3 foo[1:10] <<= 3 foo[1:10] &= 3 foo[1:10] ^= 3 foo[1:10] |= 3 """ report = TraceRunner().trace_code(code) assert trim_report(expected_report) == trim_report(report)
def test_slice_magic(): """ All augmented assignments on slices, possible with mocks. """ code = """\ from mock import MagicMock class Foo(MagicMock): def __repr__(self): return 'Foo()' foo = Foo() foo[1] = 3 foo[1:10] = 3 foo[1:10:2] = 3 foo[...] = 3 foo[1, 2:3] = 3 foo[1:10] += 3 foo[1:10] -= 3 foo[1:10] *= 3 foo[1:10] /= 3 foo[1:10] //= 3 foo[1:10] %= 3 foo[1:10] **= 3 foo[1:10] >>= 3 foo[1:10] <<= 3 foo[1:10] &= 3 foo[1:10] ^= 3 foo[1:10] |= 3 """ expected_report = """\ foo = Foo() foo[1] = 3 foo[1:10] = 3 foo[1:10:2] = 3 foo[...] = 3 foo[1, 2:3] = 3 foo[1:10] += 3 foo[1:10] -= 3 foo[1:10] *= 3 foo[1:10] /= 3 foo[1:10] //= 3 foo[1:10] %= 3 foo[1:10] **= 3 foo[1:10] >>= 3 foo[1:10] <<= 3 foo[1:10] &= 3 foo[1:10] ^= 3 foo[1:10] |= 3 """ report = CodeTracer().trace_code(code) assert trim_report(expected_report) == trim_report(report)
def test_annotated_assignment(): code = """\ i: int = 1 """ expected_report = """\ i = 1 """ report = TraceRunner().trace_code(code) assert trim_report(expected_report) == trim_report(report)
def test_assignment(): code = """\ i = 1 """ expected_report = """\ i = 1 """ report = CodeTracer().trace_code(code) assert trim_report(expected_report) == trim_report(report)
def test_increment(): code = """\ i = 1 i += 1 """ expected_report = """\ i = 1 i = 2 """ report = TraceRunner().trace_code(code) assert trim_report(expected_report) == trim_report(report)
def test_one_function_live_mode(): """ Need to keep original vertical position to line up with editor. """ code = """\ from space_tracer import traced @traced def foo(n): s = 'x' for i in range(n): s += 'y' return s def bar(num): s = 'a' for i in range(num): s += 'b' return s print(foo(3)) print(bar(3)) """ expected_report = """\ n = 3 s = 'x' i = 0 | i = 1 | i = 2 s = 'xy' | s = 'xyy' | s = 'xyyy' return 'xyyy' """ with replace_input(code): report = TraceRunner().trace_command([ 'space_tracer', '--source_width', '0', '--live', '--traced_file', 'example.py', 'example.py' ]) assert trim_report(expected_report) == trim_report(report)
def test_index_expression(): code = """\ a = [1, 2] i = 0 a[i+1] = 3 """ expected_report = """\ a = [1, 2] i = 0 a[1] = 3 """ report = TraceRunner().trace_code(code) assert trim_report(expected_report) == trim_report(report)
def test_repr_unnamed_mock(): code = """\ from unittest.mock import Mock m = Mock() """ expected_report = """\ m = Mock() """ tracer = TraceRunner() report = tracer.trace_code(code) assert trim_report(expected_report) == trim_report(report)
def test_nested_reraise(): code = """\ x = 2 try: try: raise RuntimeError('Bad stuff happened.') except: raise except: raise """ expected_report = """\ x = 2 RuntimeError: Bad stuff happened. RuntimeError: Bad stuff happened. RuntimeError: Bad stuff happened. """ tracer = CodeTracer() report = tracer.trace_code(code) assert expected_report == trim_report(report)
def test_string_io(): code = """\ from __future__ import unicode_literals from io import StringIO f = StringIO() f.write('x') """ expected_report_python2 = """\ f.write(u'x') """ expected_report_python3 = """\ f.write('x') """ expected_report = (expected_report_python3 if version_info.major >= 3 else expected_report_python2) tracer = CodeTracer() report = tracer.trace_code(code) assert expected_report == trim_report(report)
def test_repr_magic_mock(): code = """\ from unittest.mock import MagicMock m = MagicMock(name='foo') """ expected_report = """\ m = MagicMock(name='foo') """ tracer = CodeTracer() report = tracer.trace_code(code) assert trim_report(expected_report) == trim_report(report)
def test_nested_reraise(): code = """\ x = 2 try: try: raise RuntimeError('Bad stuff happened.') except: raise except: raise """ expected_report = """\ x = 2 RuntimeError: Bad stuff happened. RuntimeError: Bad stuff happened. RuntimeError: Bad stuff happened. """ tracer = TraceRunner() report = tracer.trace_code(code) assert expected_report == trim_report(report)
def test_two_functions(): code = """\ from space_tracer import traced @traced def foo(n): s = 'x' for i in range(n): s += 'y' return s @traced def bar(num): s = 'a' for i in range(num): s += 'b' return s print(foo(3)) print(bar(3)) """ expected_report = """\ @traced | def foo(n): | n = 3 s = 'x' | s = 'x' for i in range(n): | i = 0 | i = 1 | i = 2 s += 'y' | s = 'xy' | s = 'xyy' | s = 'xyyy' return s | return 'xyyy' @traced | def bar(num): | num = 3 s = 'a' | s = 'a' for i in range(num): | i = 0 | i = 1 | i = 2 s += 'b' | s = 'ab' | s = 'abb' | s = 'abbb' return s | return 'abbb' """ with replace_input(code): report = TraceRunner().trace_command([ 'space_tracer', '--source_indent', '4', '--traced_file', 'example.py', 'example.py' ]) assert trim_report(expected_report) == trim_report(report)
def test_repr_enum(): code = """\ from enum import Enum Animal = Enum('Animal', 'ANT BEE CAT DOG') eric = Animal.BEE """ expected_report = """\ eric = <Animal.BEE: 2> """ tracer = TraceRunner() report = tracer.trace_code(code) assert trim_report(expected_report) == trim_report(report)
def test_string_io_field(): code = """\ from __future__ import unicode_literals from io import StringIO class Foo: def __init__(self, f): self.f = f def greet(self, name): self.f.write('Hello, ' + name + '.') greetings = StringIO() foo = Foo(greetings) foo.greet('Alice') """ expected_report_python2 = """\ name = u'Alice' self.f.write(u'Hello, Alice.') """ expected_report_python3 = """\ name = 'Alice' self.f.write('Hello, Alice.') """ expected_report = (expected_report_python3 if version_info.major >= 3 else expected_report_python2) report = CodeTracer().trace_code(code) assert expected_report == trim_report(report)
def test_no_input(): code = """\ s = input() """ expected_report = """\ EOFError: EOF when reading a line """ report = CodeTracer().trace_code(code) assert expected_report == trim_report(report)
def test_docstring(): code = """\ '' """ expected_report = """\ """ tracer = TraceRunner() report = tracer.trace_code(code) assert expected_report == trim_report(report)
def test_assign_generator_unpacked(): code = """\ a, b = (3*i for i in range(2)) """ expected_report = """\ (a, b) = (0, 3) """ tracer = TraceRunner() report = tracer.trace_code(code) assert expected_report == trim_report(report)
def test_assign_tuple_list(): code = """\ a, [b, c] = (1, (2, 3)) """ expected_report = """\ (a, (b, c)) = (1, (2, 3)) """ tracer = CodeTracer() report = tracer.trace_code(code) assert expected_report == trim_report(report)
def test_assign_generator_unpacked(): code = """\ a, b = (3*i for i in range(2)) """ expected_report = """\ (a, b) = (0, 3) """ tracer = CodeTracer() report = tracer.trace_code(code) assert expected_report == trim_report(report)
def test_assign_tuple_list(): code = """\ a, [b, c] = (1, (2, 3)) """ expected_report = """\ (a, (b, c)) = (1, (2, 3)) """ tracer = TraceRunner() report = tracer.trace_code(code) assert expected_report == trim_report(report)
def test_docstring(): code = """\ '' """ expected_report = """\ """ tracer = CodeTracer() report = tracer.trace_code(code) assert expected_report == trim_report(report)
def test_assign_assignment(): code = """\ a = b = 2 """ expected_report = """\ a = b = 2 """ tracer = CodeTracer() report = tracer.trace_code(code) assert expected_report == trim_report(report)
def test_assign_assignment(): code = """\ a = b = 2 """ expected_report = """\ a = b = 2 """ tracer = TraceRunner() report = tracer.trace_code(code) assert expected_report == trim_report(report)
def test_augmented_assign_to_expression(): code = """\ a = [1, 2, 3] (a or None)[1] += 20 """ expected_report = """\ a = [1, 2, 3] """ report = TraceRunner().trace_code(code) assert expected_report == trim_report(report)
def test_augmented_assign_to_expression(): code = """\ a = [1, 2, 3] (a or None)[1] += 20 """ expected_report = """\ a = [1, 2, 3] """ report = CodeTracer().trace_code(code) assert expected_report == trim_report(report)
def test_assign_starred(): code = """\ a, *b = (1, 2, 3) print(b) """ expected_report = """\ (a, *b) = (1, 2, 3) print('[2, 3]') """ tracer = CodeTracer() report = tracer.trace_code(code) assert expected_report == trim_report(report)
def test_mutable_increment(): code = """\ a = [1, 2, [3, 4]] a[0] += 9 a[2][1] += 8 b = a i, j = 2, 1 a[i][j] += 7 b = a """ expected_report = """\ a = [1, 2, [3, 4]] a[0] = 10 a[2][1] = 12 b = [10, 2, [3, 12]] (i, j) = (2, 1) a[2][1] = 19 b = [10, 2, [3, 19]] """ report = CodeTracer().trace_code(code) assert trim_report(expected_report) == trim_report(report)
def test_runtime_error(): code = """\ x = 2 raise RuntimeError('Bad stuff happened.') """ expected_report = """\ x = 2 RuntimeError: Bad stuff happened. """ tracer = TraceRunner() report = tracer.trace_code(code) assert expected_report == trim_report(report)
def test_runtime_error(): code = """\ x = 2 raise RuntimeError('Bad stuff happened.') """ expected_report = """\ x = 2 RuntimeError: Bad stuff happened. """ tracer = CodeTracer() report = tracer.trace_code(code) assert expected_report == trim_report(report)
def test_assign_starred(): code = """\ a, *b = (1, 2, 3) print(b) """ expected_report = """\ (a, *b) = (1, 2, 3) print('[2, 3]') """ tracer = TraceRunner() report = tracer.trace_code(code) assert expected_report == trim_report(report)
def test_assign_to_anonymous_attribute(): code = """\ class Foo(object): pass Foo().x = 2 """ expected_report = """\ """ report = CodeTracer().trace_code(code) assert expected_report == trim_report(report)
def test_print_in_loop(): code = """\ from __future__ import print_function for i in range(3): print(i) """ expected_report = """\ i = 0 | i = 1 | i = 2 print('0') | print('1') | print('2') """ tracer = CodeTracer() report = tracer.trace_code(code) assert expected_report == trim_report(report)
def test_assign_generator_assignment(): """ Can't convert to tuple for more than one assignment. """ code = """\ a, b = c = (3*i for i in range(2)) d = a, b e = list(c) """ expected_report = """\ d = (0, 3) e = [] """ tracer = CodeTracer() report = tracer.trace_code(code) assert expected_report == trim_report(report)
def test_print_with_star(): code = """\ from __future__ import print_function args = ['Bob', 23] print(*args) """ expected_report = """\ args = ['Bob', 23] print('Bob 23') """ report = CodeTracer().trace_code(code) assert expected_report == trim_report(report)
def test_multiline_error(): code = """\ quality = 0 for c in ['1', 'x']: quality += int(c) """ expected_report = """\ quality = 0 c = '1' | c = 'x' | quality = 1 | ValueError: invalid literal for int() with base 10: 'x' """ tracer = CodeTracer() report = tracer.trace_code(code) assert expected_report == trim_report(report)
def test_stderr(capsys): code = """\ import sys s = 'x' sys.stderr.write(s) """ expected_report = """\ s = 'x' sys.stderr.write('x') """ tracer = CodeTracer() report = tracer.trace_code(code) assert expected_report == trim_report(report) std = capsys.readouterr() assert "" == std.err
def test_unwinding_exceptions(): code = """\ def foo(n): raise RuntimeError('Bad stuff happened.') x = foo(5) """ expected_report = """\ n = 5 RuntimeError: Bad stuff happened. RuntimeError: Bad stuff happened. """ tracer = CodeTracer() report = tracer.trace_code(code) assert expected_report == trim_report(report)
def test_runtime_error_caught_unnamed(): code = """\ try: raise RuntimeError('Bad stuff happened.') except: f = 'Worse stuff' """ expected_report = """\ RuntimeError: Bad stuff happened. f = 'Worse stuff' """ tracer = CodeTracer() report = tracer.trace_code(code) assert expected_report == trim_report(report)
def test_runtime_error_after_conditional(): code = """\ if False: x = 2 else: x = 3 raise RuntimeError('Bad stuff happened.') """ expected_report = """\ x = 3 RuntimeError: Bad stuff happened. """ tracer = CodeTracer() report = tracer.trace_code(code) assert expected_report == trim_report(report)
def test_print_in_function(): code = """\ from __future__ import print_function def main(): s = 'Hello, World!' print(s) main() """ expected_report = """\ s = 'Hello, World!' print('Hello, World!') """ tracer = CodeTracer() report = tracer.trace_code(code) assert expected_report == trim_report(report)
def test_print_with_sep(): code = """\ from __future__ import print_function p = 'Bob' n = 23 s = '--' print(p, n, sep=s) """ expected_report = """\ p = 'Bob' n = 23 s = '--' print('Bob--23') """ report = CodeTracer().trace_code(code) assert expected_report == trim_report(report)
def test_print(): code = """\ s = 'x' print(s) """ expected_report_python2 = """\ s = 'x' print 'x' """ expected_report_python3 = """\ s = 'x' print('x') """ expected_report = (expected_report_python3 if version_info.major >= 3 else expected_report_python2) tracer = CodeTracer() report = tracer.trace_code(code) assert expected_report == trim_report(report)
def test_runtime_error_caught(): code = """\ try: raise RuntimeError('Bad stuff happened.') except Exception as e: f = e """ expected_report = """\ RuntimeError: Bad stuff happened. e = RuntimeError('Bad stuff happened.',) f = RuntimeError('Bad stuff happened.',) """ if sys.version_info >= (3, 7, 0): expected_report = expected_report.replace(',)', ')') tracer = CodeTracer() report = tracer.trace_code(code) assert expected_report == trim_report(report)
def test_assign_tuple(): code = """\ from __future__ import print_function a = (1,) b, = (1,) (c) = (1,) (d,) = (1,) print(a) print(b) print(c) print(d) a, b = 1, 2 (c, d) = (3, 4) """ expected_report = """\ a = (1,) (b,) = (1,) c = (1,) (d,) = (1,) print('(1,)') print('1') print('(1,)') print('1') (a, b) = (1, 2) (c, d) = (3, 4) """ tracer = CodeTracer() report = tracer.trace_code(code) assert expected_report == trim_report(report)
def replace_image(report): report = trim_report(report) report = re.sub(r"image='[a-zA-Z0-9+/=]*'", "image='...'", report) return report