def test_set_trace__pytest_assert(): """Test `set_trace` fails if PyTest `assert` is encountered. PyTest also does fancy code manipulation.""" with pytest.raises( SyntaxError, match="Unable to add trace to `helper_zero_type` definition."): set_trace(helper_zero_type, trace_func)
def test_trace__multiline_no_formatting(mock_getsourcelines): for funcs, lineno, code in [ (helper_multiline_funky_one, 5, helper_multiline_funky_one_code), ]: mock_getsourcelines.side_effect = lambda fn: [[ l + "\n" for l in code.split("\n") ]] set_trace(funcs, trace_func) with pytest.warns(UserWarning, match=f"^{funcs.__name__}:{lineno}$"): funcs()
def test_trace(): """Test `set_trace` handles basic cases.""" set_trace(helper, trace_func) with pytest.warns(UserWarning, match="^helper:14$"): helper() unset_trace(helper) unset_trace(helper) set_trace(helper, trace_func) with pytest.warns(UserWarning, match="^helper:14$"): helper()
def helper_closure(): variable = "blah" def func(): return variable assert func.__code__.co_freevars == ("variable", ) # Ensure this is a closure assert func() == variable set_trace(func, trace_func) assert func() == variable
def _update_trace_globals(): """Update various globals required for tracing.""" global _code_to_func to_trace = _get_funcs_to_trace(_config) for func, config in to_trace: try: set_trace(func, trace) if _fast_trace_enabled else unset_trace(func) except SyntaxError: message = f"Unable to fast trace `{func}` on behalf of `{config}`." warnings.warn(message, NoFastTraceWarning) _code_to_func = {k.__code__: v for k, v in to_trace} _call_once.cache_clear()
def test_trace__traceback(): """Test `set_trace` handles a traceback.""" set_trace(helper_traceback, trace_func) with pytest.warns(UserWarning, match="^helper_traceback:63$"): expected = [ 'tests/test_trace.py", line 76, in test_trace__traceback', 'result = [l.strip() for l in helper_traceback().split("\\n") if len(l.strip()) > 0]', 'tests/test_trace.py", line 63, in helper_traceback', 'return "".join(traceback.format_stack(limit=2))', ] result = [ l.strip() for l in helper_traceback().split("\n") if len(l.strip()) > 0 ] assert all(e in r for r, e in zip(result, expected))
def test_set_trace__another(): """Test `set_trace` handles case where it's set again.""" set_trace(helper, trace_func) set_trace(helper, trace_func) with pytest.warns(UserWarning, match="^helper:14$"): helper() with pytest.raises(ValueError): set_trace(helper, other_trace_func) unset_trace(helper) set_trace(helper, other_trace_func) with pytest.warns(UserWarning, match="^Other: helper:14$"): helper()
def test_trace__multiline(): """Test `set_trace` handles a multiline definition.""" for funcs, lineno in [ (helper_multiline, 139), (helper_multiline_one, 147), (helper_multiline_two, 152), (func_one_liner, 155), (helper_multiline_three, 160), (helper_multiline_four, 165), (helper_multiline_five, 171), (helper_multiline_six(), 176), (helper_multiline_seven, 191), (helper_multiline_eight, 200), (helper_multiline_nine, 206), ]: set_trace(funcs, trace_func) with pytest.warns(UserWarning, match=f"^{funcs.__name__}:{lineno}$"): funcs() for class_, lineno in [(HelperMultilineObjectOne, 185), (HelperMultilineObjectTwo, 217)]: set_trace(class_.__init__, trace_func) with pytest.warns(UserWarning, match=f"^__init__:{lineno}$"): class_()
def test_trace__cellvars(): """Test `set_trace` handles cellvars.""" assert helper_cellvars.__code__.co_cellvars == ("a", ) set_trace(helper_cellvars, trace_func) with pytest.warns(UserWarning, match="^helper_cellvars:81$"): helper_cellvars()
def test_trace__globals(): """Test `set_trace` handles globals.""" set_trace(helper_globals, trace_func) with pytest.warns(UserWarning, match="^helper_globals:52$"): helper_globals([], [])
def test_trace__funky_first_line(): """Test `set_trace` handles a incomatible first line.""" with pytest.raises(SyntaxError): set_trace(helper_funky_first_line, trace_func)
def test_trace__object(): """Test `set_trace` handles objects.""" set_trace(HelperObject.__init__, trace_func) with pytest.warns(UserWarning, match="^__init__:112$"): HelperObject()
def test_trace__decorator(): """Test `set_trace` handles decorators.""" set_trace(helper_decorator, trace_func) with pytest.warns(UserWarning, match="^helper_decorator:100$"): helper_decorator()