mirror of
https://github.com/cool-RR/PySnooper.git
synced 2026-01-23 02:14:04 +00:00
Show source path, especially when multiple files
This commit is contained in:
parent
7392765ada
commit
297b3cd8d7
13 changed files with 161 additions and 20 deletions
|
|
@ -22,6 +22,7 @@ def main():
|
|||
|
||||
|
||||
expected_output = '''
|
||||
Source path:... Whatever
|
||||
12:18:08.017782 call 17 def main():
|
||||
12:18:08.018142 line 18 try:
|
||||
12:18:08.018181 line 19 bar()
|
||||
|
|
|
|||
|
|
@ -24,10 +24,12 @@ def f5():
|
|||
|
||||
|
||||
expected_output = '''
|
||||
Source path:... Whatever
|
||||
21:10:42.298924 call 5 def main():
|
||||
21:10:42.299158 line 6 f2()
|
||||
21:10:42.299205 call 9 def f2():
|
||||
21:10:42.299246 line 10 f3()
|
||||
Source path:... Whatever
|
||||
21:10:42.299305 call 18 def f4():
|
||||
21:10:42.299348 line 19 f5()
|
||||
21:10:42.299386 call 22 def f5():
|
||||
|
|
|
|||
|
|
@ -14,8 +14,9 @@ def mul(a, b):
|
|||
|
||||
def main():
|
||||
factorial(4)
|
||||
|
||||
|
||||
expected_output = '''
|
||||
Source path:... Whatever
|
||||
Starting var:.. x = 4
|
||||
20:28:17.875295 call 5 def factorial(x):
|
||||
20:28:17.875509 line 6 if x <= 1:
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ from pysnooper import pycompat
|
|||
from pysnooper.variables import needs_parentheses
|
||||
from .utils import (assert_output, assert_sample_output, VariableEntry,
|
||||
CallEntry, LineEntry, ReturnEntry, OpcodeEntry,
|
||||
ReturnValueEntry, ExceptionEntry)
|
||||
ReturnValueEntry, ExceptionEntry, SourcePathEntry)
|
||||
from . import mini_toolbox
|
||||
|
||||
|
||||
|
|
@ -36,6 +36,7 @@ def test_chinese():
|
|||
assert_output(
|
||||
output,
|
||||
(
|
||||
SourcePathEntry(),
|
||||
CallEntry(),
|
||||
LineEntry(),
|
||||
VariableEntry('a'),
|
||||
|
|
|
|||
0
tests/test_multiple_files/__init__.py
Normal file
0
tests/test_multiple_files/__init__.py
Normal file
0
tests/test_multiple_files/multiple_files/__init__.py
Normal file
0
tests/test_multiple_files/multiple_files/__init__.py
Normal file
6
tests/test_multiple_files/multiple_files/bar.py
Normal file
6
tests/test_multiple_files/multiple_files/bar.py
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# Copyright 2019 Ram Rachum and collaborators.
|
||||
# This program is distributed under the MIT license.
|
||||
|
||||
def bar_function(y):
|
||||
x = 7 * y
|
||||
return x
|
||||
11
tests/test_multiple_files/multiple_files/foo.py
Normal file
11
tests/test_multiple_files/multiple_files/foo.py
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
# Copyright 2019 Ram Rachum and collaborators.
|
||||
# This program is distributed under the MIT license.
|
||||
|
||||
import pysnooper
|
||||
|
||||
from .bar import bar_function
|
||||
|
||||
@pysnooper.snoop(depth=2)
|
||||
def foo_function():
|
||||
z = bar_function(3)
|
||||
return z
|
||||
51
tests/test_multiple_files/test_multiple_files.py
Normal file
51
tests/test_multiple_files/test_multiple_files.py
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
# Copyright 2019 Ram Rachum and collaborators.
|
||||
# This program is distributed under the MIT license.
|
||||
|
||||
import io
|
||||
import textwrap
|
||||
import threading
|
||||
import types
|
||||
import os
|
||||
import sys
|
||||
|
||||
from pysnooper.utils import truncate
|
||||
import pytest
|
||||
|
||||
import pysnooper
|
||||
from pysnooper.variables import needs_parentheses
|
||||
from ..utils import (assert_output, assert_sample_output, VariableEntry,
|
||||
CallEntry, LineEntry, ReturnEntry, OpcodeEntry,
|
||||
ReturnValueEntry, ExceptionEntry, SourcePathEntry)
|
||||
from .. import mini_toolbox
|
||||
from .multiple_files import foo
|
||||
|
||||
|
||||
def test_multiple_files():
|
||||
with mini_toolbox.OutputCapturer(stdout=False,
|
||||
stderr=True) as output_capturer:
|
||||
result = foo.foo_function()
|
||||
assert result == 21
|
||||
output = output_capturer.string_io.getvalue()
|
||||
assert_output(
|
||||
output,
|
||||
(
|
||||
SourcePathEntry(source_path_regex=r'.*foo\.py$'),
|
||||
CallEntry(),
|
||||
LineEntry(),
|
||||
SourcePathEntry(source_path_regex=r'.*bar\.py$'),
|
||||
VariableEntry(),
|
||||
CallEntry(),
|
||||
LineEntry(),
|
||||
VariableEntry(),
|
||||
LineEntry(),
|
||||
ReturnEntry(),
|
||||
ReturnValueEntry(),
|
||||
SourcePathEntry(source_path_regex=r'.*foo\.py$'),
|
||||
VariableEntry(),
|
||||
LineEntry(),
|
||||
ReturnEntry(),
|
||||
ReturnValueEntry(),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -15,7 +15,7 @@ import pysnooper
|
|||
from pysnooper.variables import needs_parentheses
|
||||
from .utils import (assert_output, assert_sample_output, VariableEntry,
|
||||
CallEntry, LineEntry, ReturnEntry, OpcodeEntry,
|
||||
ReturnValueEntry, ExceptionEntry)
|
||||
ReturnValueEntry, ExceptionEntry, SourcePathEntry)
|
||||
from . import mini_toolbox
|
||||
|
||||
|
||||
|
|
@ -34,6 +34,7 @@ def test_string_io():
|
|||
assert_output(
|
||||
output,
|
||||
(
|
||||
SourcePathEntry(),
|
||||
VariableEntry('foo', value_regex="u?'baba'"),
|
||||
CallEntry('def my_function(foo):'),
|
||||
LineEntry('x = 7'),
|
||||
|
|
@ -63,6 +64,7 @@ def test_thread_info():
|
|||
assert_output(
|
||||
output,
|
||||
(
|
||||
SourcePathEntry(),
|
||||
VariableEntry('foo', value_regex="u?'baba'"),
|
||||
CallEntry('def my_function(foo):'),
|
||||
LineEntry('x = 7'),
|
||||
|
|
@ -105,6 +107,7 @@ def test_multi_thread_info():
|
|||
assert_output(
|
||||
output,
|
||||
(
|
||||
SourcePathEntry(),
|
||||
VariableEntry('foo', value_regex="u?'baba'"),
|
||||
CallEntry('def my_function(foo):',
|
||||
thread_info_regex=thread_info_regex.format(
|
||||
|
|
@ -174,6 +177,7 @@ def test_callable():
|
|||
assert_output(
|
||||
output,
|
||||
(
|
||||
SourcePathEntry(),
|
||||
VariableEntry('foo', value_regex="u?'baba'"),
|
||||
CallEntry('def my_function(foo):'),
|
||||
LineEntry('x = 7'),
|
||||
|
|
@ -215,6 +219,7 @@ def test_watch():
|
|||
assert_output(
|
||||
output,
|
||||
(
|
||||
SourcePathEntry(),
|
||||
VariableEntry('Foo'),
|
||||
VariableEntry('io.__name__', "'io'"),
|
||||
CallEntry('def my_function():'),
|
||||
|
|
@ -261,6 +266,7 @@ def test_watch_explode():
|
|||
assert_output(
|
||||
output,
|
||||
(
|
||||
SourcePathEntry(),
|
||||
VariableEntry('Foo'),
|
||||
CallEntry('def my_function():'),
|
||||
LineEntry(),
|
||||
|
|
@ -315,6 +321,7 @@ def test_variables_classes():
|
|||
assert_output(
|
||||
output,
|
||||
(
|
||||
SourcePathEntry(),
|
||||
VariableEntry('WithSlots'),
|
||||
CallEntry('def my_function():'),
|
||||
LineEntry(),
|
||||
|
|
@ -360,6 +367,7 @@ def test_single_watch_no_comma():
|
|||
assert_output(
|
||||
output,
|
||||
(
|
||||
SourcePathEntry(),
|
||||
VariableEntry('Foo'),
|
||||
CallEntry('def my_function():'),
|
||||
LineEntry('foo = Foo()'),
|
||||
|
|
@ -392,6 +400,7 @@ def test_long_variable():
|
|||
assert_output(
|
||||
output,
|
||||
(
|
||||
SourcePathEntry(),
|
||||
CallEntry('def my_function():'),
|
||||
LineEntry('foo = list(range(1000))'),
|
||||
VariableEntry('foo', value_regex=regex),
|
||||
|
|
@ -419,6 +428,7 @@ def test_repr_exception():
|
|||
assert_output(
|
||||
output,
|
||||
(
|
||||
SourcePathEntry(),
|
||||
VariableEntry('Bad'),
|
||||
CallEntry('def my_function():'),
|
||||
LineEntry('bad = Bad()'),
|
||||
|
|
@ -455,6 +465,7 @@ def test_depth():
|
|||
assert_output(
|
||||
output,
|
||||
(
|
||||
SourcePathEntry(),
|
||||
VariableEntry(),
|
||||
VariableEntry(),
|
||||
CallEntry('def f1(x1):'),
|
||||
|
|
@ -510,6 +521,7 @@ def test_method_and_prefix():
|
|||
assert_output(
|
||||
output,
|
||||
(
|
||||
SourcePathEntry(prefix='ZZZ'),
|
||||
VariableEntry('self', prefix='ZZZ'),
|
||||
VariableEntry('self.x', '2', prefix='ZZZ'),
|
||||
CallEntry('def square(self):', prefix='ZZZ'),
|
||||
|
|
@ -542,6 +554,7 @@ def test_file_output():
|
|||
assert_output(
|
||||
output,
|
||||
(
|
||||
SourcePathEntry(),
|
||||
VariableEntry('_foo', value_regex="u?'baba'"),
|
||||
CallEntry('def my_function(_foo):'),
|
||||
LineEntry('x = 7'),
|
||||
|
|
@ -577,6 +590,7 @@ def test_confusing_decorator_lines():
|
|||
assert_output(
|
||||
output,
|
||||
(
|
||||
SourcePathEntry(),
|
||||
VariableEntry('foo', value_regex="u?'baba'"),
|
||||
CallEntry('def my_function(foo):'),
|
||||
LineEntry(),
|
||||
|
|
@ -606,6 +620,7 @@ def test_lambda():
|
|||
assert_output(
|
||||
output,
|
||||
(
|
||||
SourcePathEntry(),
|
||||
VariableEntry('x', '7'),
|
||||
CallEntry(source_regex='^my_function = pysnooper.*'),
|
||||
LineEntry(source_regex='^my_function = pysnooper.*'),
|
||||
|
|
@ -638,6 +653,7 @@ def test_unavailable_source():
|
|||
assert_output(
|
||||
output,
|
||||
(
|
||||
SourcePathEntry(),
|
||||
VariableEntry(stage='starting'),
|
||||
CallEntry('SOURCE IS UNAVAILABLE'),
|
||||
LineEntry('SOURCE IS UNAVAILABLE'),
|
||||
|
|
@ -666,6 +682,7 @@ def test_no_overwrite_by_default():
|
|||
assert_output(
|
||||
shortened_output,
|
||||
(
|
||||
SourcePathEntry(),
|
||||
VariableEntry('foo', value_regex="u?'baba'"),
|
||||
CallEntry('def my_function(foo):'),
|
||||
LineEntry('x = 7'),
|
||||
|
|
@ -698,6 +715,7 @@ def test_overwrite():
|
|||
assert_output(
|
||||
output,
|
||||
(
|
||||
SourcePathEntry(),
|
||||
VariableEntry('foo', value_regex="u?'baba'"),
|
||||
CallEntry('def my_function(foo):'),
|
||||
LineEntry('x = 7'),
|
||||
|
|
@ -793,6 +811,7 @@ def test_with_block():
|
|||
output,
|
||||
(
|
||||
# In first with
|
||||
SourcePathEntry(),
|
||||
VariableEntry('x', '2'),
|
||||
VariableEntry('bar1'),
|
||||
VariableEntry('bar2'),
|
||||
|
|
@ -897,6 +916,7 @@ def test_with_block_depth():
|
|||
assert_output(
|
||||
output,
|
||||
(
|
||||
SourcePathEntry(),
|
||||
VariableEntry(),
|
||||
VariableEntry(),
|
||||
VariableEntry(),
|
||||
|
|
@ -948,6 +968,7 @@ def test_cellvars():
|
|||
assert_output(
|
||||
output,
|
||||
(
|
||||
SourcePathEntry(),
|
||||
VariableEntry(),
|
||||
VariableEntry(),
|
||||
VariableEntry(),
|
||||
|
|
@ -1002,6 +1023,7 @@ def test_var_order():
|
|||
assert_output(
|
||||
output,
|
||||
(
|
||||
SourcePathEntry(),
|
||||
VariableEntry(),
|
||||
VariableEntry(),
|
||||
|
||||
|
|
@ -1087,6 +1109,7 @@ def test_generator():
|
|||
assert_output(
|
||||
output,
|
||||
(
|
||||
SourcePathEntry(),
|
||||
VariableEntry('x1', '0'),
|
||||
VariableEntry(),
|
||||
CallEntry(),
|
||||
|
|
@ -1162,6 +1185,7 @@ def test_custom_repr():
|
|||
assert_output(
|
||||
output,
|
||||
(
|
||||
SourcePathEntry(),
|
||||
VariableEntry('x', '10000'),
|
||||
CallEntry(),
|
||||
LineEntry(),
|
||||
|
|
@ -1188,6 +1212,7 @@ def test_custom_repr_single():
|
|||
assert_output(
|
||||
output,
|
||||
(
|
||||
SourcePathEntry(),
|
||||
VariableEntry('x', '10000'),
|
||||
CallEntry(),
|
||||
LineEntry(),
|
||||
|
|
|
|||
|
|
@ -167,6 +167,31 @@ class ReturnValueEntry(_BaseValueEntry):
|
|||
else:
|
||||
return True
|
||||
|
||||
class SourcePathEntry(_BaseValueEntry):
|
||||
def __init__(self, source_path=None, source_path_regex=None, prefix=''):
|
||||
_BaseValueEntry.__init__(self, prefix=prefix)
|
||||
if source_path is not None:
|
||||
assert source_path_regex is None
|
||||
|
||||
self.source_path = source_path
|
||||
self.source_path_regex = (None if source_path_regex is None else
|
||||
re.compile(source_path_regex))
|
||||
|
||||
_preamble_pattern = re.compile(
|
||||
r"""^Source path$"""
|
||||
)
|
||||
|
||||
def _check_preamble(self, preamble):
|
||||
return bool(self._preamble_pattern.match(preamble))
|
||||
|
||||
def _check_content(self, source_path):
|
||||
if self.source_path is not None:
|
||||
return source_path == self.source_path
|
||||
elif self.source_path_regex is not None:
|
||||
return self.source_path_regex.match(source_path)
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
class _BaseEventEntry(_BaseEntry):
|
||||
def __init__(self, source=None, source_regex=None, thread_info=None,
|
||||
|
|
@ -278,7 +303,15 @@ def assert_sample_output(module):
|
|||
time_pattern = re.sub(r'\d', r'\\d', time)
|
||||
|
||||
def normalise(out):
|
||||
return re.sub(time_pattern, time, out).strip()
|
||||
out = re.sub(time_pattern, time, out).strip()
|
||||
out = re.sub(
|
||||
r'^( *)Source path:\.\.\. .*$',
|
||||
r'\1Source path:... Whatever',
|
||||
out,
|
||||
flags=re.MULTILINE
|
||||
)
|
||||
return out
|
||||
|
||||
|
||||
output = output_capturer.string_io.getvalue()
|
||||
|
||||
|
|
@ -290,3 +323,5 @@ def assert_sample_output(module):
|
|||
except AssertionError:
|
||||
print('\n\nActual Output:\n\n' + output) # to copy paste into expected_output
|
||||
raise # show pytest diff (may need -vv flag to see in full)
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue