Skip to content

unittest.mock.patch with autospec doesn't hold for classmethods nor staticmethods #102978

Closed

Description

@rileyjohngibbs

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

Linked PRs

Activity

  1. added
    stdlibStandard Library Python modules in the Lib/ directory
    on Apr 1, 2023
  2. tomasr8 commented on Apr 3, 2023

    @tomasr8
    Member

    Looks like the signature is not set for @classmethod and @staticmethod. Adding a special case for them and using __func__ to get the correct signature I was able to get it to work. I'll see if I can contribute a PR that fixes this.

  3. arhadthedev commented on Apr 13, 2023

    @arhadthedev
    Member

    @cjw296 Can this issue be considered completed? The child PR gh-103228 is neither merged nor backported yet.

  4. added a commit that references this issue on Apr 13, 2023
  5. added a commit that references this issue on Apr 13, 2023