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
Activity