diff --git a/coverage/context.py b/coverage/context.py index 977e9b4ef..537f17efe 100644 --- a/coverage/context.py +++ b/coverage/context.py @@ -64,7 +64,10 @@ def qualname_from_frame(frame: FrameType) -> str | None: if method is None: func = frame.f_globals.get(fname) if func is None: - return None + try: + return frame.f_code.co_qualname + except AttributeError: + return f"staticmethod({fname})" return cast(str, func.__module__ + "." + fname) func = getattr(method, "__func__", None) diff --git a/tests/test_context.py b/tests/test_context.py index 5c0618c02..4fe789888 100644 --- a/tests/test_context.py +++ b/tests/test_context.py @@ -230,6 +230,14 @@ def meth(self) -> str | None: def a_property(self) -> str | None: return get_qualname() + @staticmethod + def statmeth() -> str | None: + return get_qualname() + + @classmethod + def classmeth(cls) -> str | None: + return get_qualname() + class Child(Parent): pass @@ -283,6 +291,12 @@ def test_fake_out(self) -> None: def test_property(self) -> None: assert Parent().a_property == "tests.test_context.Parent.a_property" + def test_staticmethod(self) -> None: + assert Parent().statmeth() == "xyzzy" + + def test_classmethod(self) -> None: + assert Parent().classmeth() == "xyzzy" + def test_changeling(self) -> None: c = Child() c.meth = patch_meth # type: ignore[assignment]