Closed
Description
Bug report
Using patch
with autospec=True
does not work when a method is decorated with @classmethod
or @staticmethod
. The resulting mock can be called with any arguments without raising a TypeError
.
Example:
from unittest.mock import patch import pytest class Foo: def foo(self): pass @staticmethod def bar(): pass @classmethod def baz(cls): pass @pytest.mark.parametrize("method", ["foo", "bar", "baz"]) def test_foo(method: str): with patch.object(Foo, method, autospec=True): getattr(Foo(), method)(5)
The only subtest that fails is foo
. The other two pass, even though they're clearly being called incorrectly.
If you prefer not to use pytest
to demo/repro this:
with patch.object(Foo, "foo", autospec=True): try: Foo().foo(5) except TypeError: print("Correctly raises on foo") else: print("Incorrectly does not raise with foo") with patch.object(Foo, "bar", autospec=True): try: Foo().bar(5) except TypeError: print("Correctly raises on bar") else: print("Incorrectly does not raise with bar") with patch.object(Foo, "baz", autospec=True): try: Foo().baz(5) except TypeError: print("Correctly raises on baz") else: print("Incorrectly does not raise with baz")
This has output:
Correctly raises on foo Incorrectly does not raise with bar Incorrectly does not raise with baz
Your environment
- CPython versions tested on: 3.10, 3.11
- Operating system and architecture: macOS 12.6 with Apple M1 chip