def test_registration_through_code_object(isolated_registry): def code_example(magic_arg): return asynctb.Traceback.since(sys._getframe(0)) asynctb.customize(code_example.__code__, get_target=simple_get_target) tb = code_example(100) assert [f.funcname for f in tb.frames] == ["code_example", "fake_target"]
def test_registration_through_nested(isolated_registry): def outer_fn(magic_arg): def middle_fn(): def inner_fn(): assert magic_arg == 1 return current_frame_uses_registered_get_target() assert magic_arg == 1 assert current_frame_uses_registered_get_target() return inner_fn assert not current_frame_uses_registered_get_target() return middle_fn asynctb.customize(outer_fn, "middle_fn", get_target=simple_get_target) with pytest.raises(ValueError, match="function or class named"): asynctb.customize(outer_fn, "magic_arg") with pytest.raises(ValueError, match="function or class named"): asynctb.customize(outer_fn, "nope") middle_fn = outer_fn(1) inner_fn = middle_fn() assert not inner_fn() asynctb.customize(outer_fn, "middle_fn", "inner_fn", get_target=simple_get_target) assert inner_fn()
def test_registration_through_functools_wraps_or_partial(isolated_registry): def example(magic_arg): return asynctb.Traceback.since(sys._getframe(0)) @wraps(example) def wrapper(something): return example(something) bound_example = partial(wrapper, 10) asynctb.customize(bound_example, get_target=simple_get_target) tb = bound_example() assert len(tb.frames) == 2 assert [f.funcname for f in tb.frames] == ["example", "fake_target"] assert tb.frames[-1].frame.f_locals["arg"] == 10
def glue_two(): record.append("two") two_waiting.set() one_started.wait() two_started.set() asynctb.customize(two_fn, skip_frame=True)
def glue_one(): record.append("one") one_started.set() two_started.wait() asynctb.customize(one_fn, skip_frame=True)
def test_registration_through_unsupported(): with pytest.raises(TypeError, match="extract a code object"): asynctb.customize(42, skip_frame=True)