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

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

Closed
rileyjohngibbs opened this issue Mar 23, 2023 · 2 comments · Fixed by #103228
Closed
Labels
stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error

Comments

@rileyjohngibbs
Copy link

rileyjohngibbs commented Mar 23, 2023

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

@rileyjohngibbs rileyjohngibbs added the type-bug An unexpected behavior, bug, or error label Mar 23, 2023
@arhadthedev arhadthedev added the stdlib Python modules in the Lib dir label Apr 1, 2023
@tomasr8
Copy link
Member

tomasr8 commented Apr 3, 2023

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.

@arhadthedev
Copy link
Member

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

miss-islington pushed a commit to miss-islington/cpython that referenced this issue Apr 13, 2023
…ticmethod decorators (pythonGH-103228)

Fixes unittest.mock.patch not enforcing function signatures for methods
decorated with @classmethod or @staticmethod when patch is called with
autospec=True.
(cherry picked from commit 59e0de4)

Co-authored-by: Tomas R <tomas.roun8@gmail.com>
cjw296 pushed a commit that referenced this issue Apr 13, 2023
…hod decorators (#103228)

Fixes unittest.mock.patch not enforcing function signatures for methods
decorated with @classmethod or @staticmethod when patch is called with
autospec=True.
carljm added a commit to carljm/cpython that referenced this issue Apr 13, 2023
* main:
  pythongh-103479: [Enum] require __new__ to be considered a data type (pythonGH-103495)
  pythongh-103365: [Enum] STRICT boundary corrections (pythonGH-103494)
  pythonGH-103488: Use return-offset, not yield-offset. (pythonGH-103502)
  pythongh-103088: Fix test_venv error message to avoid bytes/str warning (pythonGH-103500)
  pythonGH-103082: Turn on branch events for FOR_ITER instructions. (python#103507)
  pythongh-102978: Fix mock.patch function signatures for class and staticmethod decorators (python#103228)
  pythongh-103462: Ensure SelectorSocketTransport.writelines registers a writer when data is still pending (python#103463)
  pythongh-95299: Rework test_cppext.py to not invoke setup.py directly (python#103316)
aisk pushed a commit to aisk/cpython that referenced this issue Apr 18, 2023
…ticmethod decorators (python#103228)

Fixes unittest.mock.patch not enforcing function signatures for methods
decorated with @classmethod or @staticmethod when patch is called with
autospec=True.
ambv pushed a commit that referenced this issue May 22, 2023
…aticmethod decorators (GH-103228) (#103499)

Fixes unittest.mock.patch not enforcing function signatures for methods
decorated with @classmethod or @staticmethod when patch is called with
autospec=True.

(cherry picked from commit 59e0de4)

Co-authored-by: Tomas R <tomas.roun8@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants