Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add test cases to improve coverage stat #452

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions testing/test_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,46 @@ class F:
assert varnames(F) == ((), ())


def test_varnames_catch_all() -> None:
"""
Adding coverage for special cases. According to the code in varnames(), we should handle
several unusual exception-throwing scenarios.
"""

class NoInitMeta(type):
def __getattribute__(self, item):
if item == "__init__":
raise AttributeError(
"Testing a class where we can't look at the __init__ attr"
)
else:
return object.__getattribute__(self, item)

class NoInit(metaclass=NoInitMeta):
"""A class that throws AttributeError for '__init__'"""

class CantCallMe:
def __getattribute__(self, item):
if item == "__call__":
raise ValueError("Don't look at me")
else:
return object.__getattribute__(self, item)

def __call__(self, *args, **kwargs):
pass

def has_weird_signature():
pass

setattr(
has_weird_signature, "__signature__", "inspect will fail b/c this is a string"
)

assert varnames(NoInit) == ((), ())
assert varnames(CantCallMe()) == ((), ())
assert varnames(has_weird_signature) == ((), ())


def test_varnames_keyword_only() -> None:
def f1(x, *, y) -> None:
pass
Expand Down
99 changes: 93 additions & 6 deletions testing/test_multicall.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,17 +249,35 @@ def m1():
assert out == ["cleanup", "finally"]


@pytest.mark.parametrize(
"wrapper_style_new", [True, False], ids=["new-style", "old-style"]
)
@pytest.mark.parametrize("exc", [ValueError, SystemExit])
def test_hookwrapper_exception(exc: "Type[BaseException]") -> None:
def test_hookwrapper_exception(exc: "Type[BaseException]", wrapper_style_new) -> None:
out = []

@hookimpl(hookwrapper=True)
if wrapper_style_new:
as_wrapper = hookimpl(wrapper=True)
else:
as_wrapper = hookimpl(hookwrapper=True)

@as_wrapper
def m1():
out.append("m1 init")
result = yield
assert isinstance(result.exception, exc)
assert result.excinfo[0] == exc
out.append("m1 finish")

if wrapper_style_new:
try:
_ = yield
pytest.fail("yield is expected to raise an exception here")
except BaseException as e:
assert isinstance(e, exc)
out.append("m1 finish")
raise e
else:
result = yield
assert isinstance(result.exception, exc)
assert result.excinfo[0] == exc
out.append("m1 finish")

@hookimpl
def m2():
Expand Down Expand Up @@ -345,6 +363,75 @@ def m2():
assert out == ["m1 init", "m2 init", "m1 finish"]


@pytest.mark.parametrize("raise_exception_at", ["exc-before", "exc-after"])
@pytest.mark.parametrize(
"has_second_yield", [True, False], ids=["with-second-yield", "no-second-yield"]
)
@pytest.mark.parametrize(
"wrapper_style_new", [True, False], ids=["new-style", "old-style"]
)
@pytest.mark.parametrize(
"hook_throws", [True, False], ids=["hook-throws", "hook-returns"]
)
def test_wrapper_raises_exception(
wrapper_style_new, raise_exception_at, has_second_yield, hook_throws
):
out = []
if wrapper_style_new:
as_wrapper = hookimpl(wrapper=True)
else:
as_wrapper = hookimpl(hookwrapper=True)

@as_wrapper
def m1():
out.append("m1 init")
if raise_exception_at == "exc-before":
raise ValueError("Raising early exception")

_ = yield

if raise_exception_at == "exc-after":
raise ValueError("Raising late exception")

out.append("should not see this")

@hookimpl(wrapper=True)
def m2():
out.append("m2 init")
if raise_exception_at == "exc-before":
raise ValueError("m2: Raising early exception")

_ = yield

if has_second_yield:
_ = yield

if raise_exception_at == "exc-after":
raise ValueError("m2: Raising late exception")

out.append("m2 should not see this")

@hookimpl
def m3():
if hook_throws:
raise ValueError("Hook failed!")
else:
return 123

if has_second_yield and raise_exception_at == "exc-after" and not hook_throws:
expect_exception: Type[Exception] = RuntimeError
else:
expect_exception = ValueError

with pytest.raises(expect_exception):
MC([m3, m2, m1], {})

if raise_exception_at == "exc-before":
assert out == ["m1 init"]
else:
assert out == ["m1 init", "m2 init"]


def test_wrapper_exception_chaining() -> None:
@hookimpl
def m1():
Expand Down
Loading