Issue 23078: unittest.mock patch autospec doesn't work on staticmethods (original) (raw)

process

Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: berker.peksag Nosy List: Claudiu.Popa, John Parejko2, atenni, berker.peksag, cjw296, deanliao, epu, fov, galuszkak, germanop, kevinbenton, kormat, lukasz.langa, mariocj89, michael.foord, parejkoj-3, tom.dalton.fanduel, xtreak
Priority: normal Keywords: patch

Created on 2014-12-18 08:45 by kevinbenton, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
issue23078.patch Claudiu.Popa,2015-01-22 09:20
issue23078.patch Claudiu.Popa,2015-01-22 17:05 review
issue23078.patch fov,2015-09-15 00:05 Update mock._callable to properly detect classmethod/staticmethod callables review
Pull Requests
URL Status Linked Edit
PR 11613 merged xtreak,2019-01-18 17:46
PR 12901 merged berker.peksag,2019-04-22 02:47
Messages (19)
msg232864 - (view) Author: Kevin Benton (kevinbenton) Date: 2014-12-18 08:45
If one of the mock.patch methods is used with autospec=True on a staticmethod in an object, the mock library determines that it is not callable by checking for the __call__ attribute. This results in a NonCallableMagicMock being returned which of course dies with the following error when the mocked method is called: TypeError: 'NonCallableMagicMock' object is not callable It seems that the create_autospec needs to special case for classmethod and staticmethod. The following change seems to fix it, however I am only vaguely familiar with the internals of mock so I'm not sure what this breaks. diff -r d356250e275d mock.py --- a/mock.py Tue Apr 09 14:53:33 2013 +0100 +++ b/mock.py Wed Dec 17 07:35:15 2014 -0800 @@ -2191,7 +2191,8 @@ # descriptors don't have a spec # because we don't know what type they return _kwargs = {} - elif not _callable(spec): + elif not _callable(spec) and not isinstance(spec, (staticmethod, + classmethod)): Klass = NonCallableMagicMock elif is_type and instance and not _instance_callable(spec): Klass = NonCallableMagicMock
msg234486 - (view) Author: PCManticore (Claudiu.Popa) * (Python triager) Date: 2015-01-22 09:20
Here's a patch which does this. One problem could be that staticmethod(some_callable) or classmethod(some_callable) aren't callable per se, but given the fact that users expects Foo.staticmethod or Foo.klassmethod to be callable when patching them, it's something we should consider for fixing.
msg234501 - (view) Author: Berker Peksag (berker.peksag) * (Python committer) Date: 2015-01-22 17:01
Looks like b6ea3dc89a78 is not a valid changeset. Could you attach a patch from the Mercurial repo?
msg234502 - (view) Author: PCManticore (Claudiu.Popa) * (Python triager) Date: 2015-01-22 17:02
Ups, sorry about that, I'll update the patch.
msg244677 - (view) Author: Felipe (fov) * Date: 2015-06-02 16:27
Regarding Claudiu's comment about `staticmethod(x)` or `classmethod(x)` not being callable, would it suffice to add a specific check of the form `(isinstance(x, (classmethod, staticmethod)) and _callable(x.__func__))`? Separately, would it be better to include the check for `staticmethod` and `classmethod` objects (with an underlying callable) inside the `_callable` function? Not sure if this would break anything, but it seems like conceptually the issue is with the definition of a callable object, not the selection of mock type to use.
msg250716 - (view) Author: Felipe (fov) * Date: 2015-09-15 00:05
The attached patch implements these changes through _callable instead. This patch also ensures that the underlying object that staticmethod and classmethod wrap is a callable object as well.
msg305823 - (view) Author: Germano (germanop) Date: 2017-11-08 11:52
Hi, I hit this problem wile mocking one static method and found this fix. Tested it and works for me. However, I did not find it pushed anywhere: no Python 3.x and no mock for 2.7. Is there any reason why it is not pushed anywhere, yet?
msg310728 - (view) Author: Dean Liao (deanliao) Date: 2018-01-26 02:59
I planned to upgrade Chromium OS's mock module to 2.0.0. I also encountered the issue that classmethod cannot be patched as callable mock. Reviewers, can we start the review process?
msg322849 - (view) Author: Kamil Gałuszka (galuszkak) * Date: 2018-08-01 08:09
This affects all versions from 3.4 up to 3.8-dev. Would be nice if someone could do the review of the supplied patch. Thanks for awesome work on Python! I'm here because it just hit me also and I was for 1 h thinking that I don't know how to use patch/mock. ;)
msg330433 - (view) Author: Tom Dalton (tom.dalton.fanduel) Date: 2018-11-26 14:22
I've just come across this too, so would be great if the patch can be progressed.
msg330434 - (view) Author: Tom Dalton (tom.dalton.fanduel) Date: 2018-11-26 14:46
Here's a minimal example so my comment is not totally vacuous: ``` import unittest from unittest import mock class Foo: @classmethod def bar(cls, baz): pass class TestFoo(unittest.TestCase): def test_bar(self): with unittest.mock.patch.object(Foo, "bar", autospec=True): Foo.bar() ``` -> ``` ~/› python -m unittest example.py E ====================================================================== ERROR: test_bar (example.TestFoo) ---------------------------------------------------------------------- Traceback (most recent call last): File "example.py", line 14, in test_bar Foo.bar() TypeError: 'NonCallableMagicMock' object is not callable ---------------------------------------------------------------------- Ran 1 test in 0.001s ```
msg330569 - (view) Author: John Parejko (John Parejko2) Date: 2018-11-28 01:58
Adding to the list of "I just ran into this". The patch submitted by fov seems straightforward enough: what can we do to help shepherd it along?
msg330570 - (view) Author: Berker Peksag (berker.peksag) * (Python committer) Date: 2018-11-28 02:05
Thanks for the pings. I will work on this issue this weekend. Note that 3.4 and 3.5 are in security-fix-only mode now, so I removed them from the versions field.
msg333734 - (view) Author: John Parejko (parejkoj-3) Date: 2019-01-15 22:10
Were you able to make any progress on this? Do you need any help?
msg333836 - (view) Author: Karthikeyan Singaravelan (xtreak) * (Python committer) Date: 2019-01-17 09:42
@berker.peksag I have converted the patch at https://bugs.python.org/file40470/issue23078.patch and pushed it to a GitHub branch https://github.com/python/cpython/compare/master...tirkarthi:bpo23078 . I am willing to open a PR attributing to @fov in case you haven't had the time to look into this. I am removing 3.6 since it's security fixes only mode. Thanks
msg333892 - (view) Author: Felipe (fov) * Date: 2019-01-17 18:28
Please go ahead with the PR. I can't push this one through, but would be great to have this finally land! On Thu, 17 Jan 2019 at 03:42, Karthikeyan Singaravelan < report@bugs.python.org> wrote: > > Karthikeyan Singaravelan <tir.karthi@gmail.com> added the comment: > > @berker.peksag I have converted the patch at > https://bugs.python.org/file40470/issue23078.patch and pushed it to a > GitHub branch > https://github.com/python/cpython/compare/master...tirkarthi:bpo23078 . I > am willing to open a PR attributing to @fov in case you haven't had the > time to look into this. > > I am removing 3.6 since it's security fixes only mode. > > Thanks > > ---------- > nosy: +cjw296, mariocj89, xtreak > versions: -Python 3.6 > > _______________________________________ > Python tracker <report@bugs.python.org> > <https://bugs.python.org/issue23078> > _______________________________________ >
msg340633 - (view) Author: Berker Peksag (berker.peksag) * (Python committer) Date: 2019-04-22 02:30
New changeset 9b21856b0fcda949de239edc7aa6cf3f2f4f77a3 by Berker Peksag (Xtreak) in branch 'master': bpo-23078: Add support for {class,static}method to mock.create_autospec() (GH-11613) https://github.com/python/cpython/commit/9b21856b0fcda949de239edc7aa6cf3f2f4f77a3
msg340635 - (view) Author: Berker Peksag (berker.peksag) * (Python committer) Date: 2019-04-22 03:07
New changeset 15a57a3cadb992bb1752302333ff593e7eab284c by Berker Peksag in branch '3.7': bpo-23078: Add support for {class,static}method to mock.create_autospec() (GH-11613) https://github.com/python/cpython/commit/15a57a3cadb992bb1752302333ff593e7eab284c
msg340636 - (view) Author: Berker Peksag (berker.peksag) * (Python committer) Date: 2019-04-22 03:08
Thank you!
History
Date User Action Args
2022-04-11 14:58:11 admin set github: 67267
2019-04-22 03:08:29 berker.peksag set status: open -> closedresolution: fixedmessages: + stage: patch review -> resolved
2019-04-22 03:07:58 berker.peksag set messages: +
2019-04-22 02:47:02 berker.peksag set pull_requests: + <pull%5Frequest12829>
2019-04-22 02:31:15 berker.peksag set pull_requests: - <pull%5Frequest11349>
2019-04-22 02:30:25 berker.peksag set messages: +
2019-01-18 17:47:15 xtreak set pull_requests: + <pull%5Frequest11349>
2019-01-18 17:46:48 xtreak set pull_requests: + <pull%5Frequest11348>
2019-01-17 18:28:55 fov set messages: +
2019-01-17 09:42:31 xtreak set nosy: + cjw296, xtreak, mariocj89messages: + versions: - Python 3.6
2019-01-15 22:10:44 parejkoj-3 set nosy: + parejkoj-3messages: +
2018-12-10 06:55:19 atenni set nosy: + atenni
2018-11-28 02:05:38 berker.peksag set assignee: berker.peksagmessages: + versions: - Python 3.4, Python 3.5
2018-11-28 01:58:02 John Parejko2 set nosy: + John Parejko2messages: +
2018-11-26 14:46:50 tom.dalton.fanduel set messages: +
2018-11-26 14:22:20 tom.dalton.fanduel set nosy: + tom.dalton.fanduelmessages: +
2018-08-01 08:09:51 galuszkak set nosy: + galuszkakmessages: + versions: + Python 3.6, Python 3.7, Python 3.8
2018-01-26 02:59:15 deanliao set nosy: + deanliaomessages: +
2017-11-08 11:52:18 germanop set nosy: + germanopmessages: +
2016-02-10 17:27:22 epu set nosy: + epu
2015-09-15 00:05:30 fov set files: + issue23078.patchmessages: +
2015-08-18 14:33:44 kormat set nosy: + kormat
2015-06-02 16:27:05 fov set nosy: + fovmessages: +
2015-04-14 15:16:05 kjachim set nosy: + lukasz.langa
2015-01-22 17:05:21 Claudiu.Popa set files: + issue23078.patch
2015-01-22 17:02:27 Claudiu.Popa set messages: +
2015-01-22 17:01:33 berker.peksag set nosy: + berker.peksagmessages: + versions: - Python 2.7
2015-01-22 09:20:16 Claudiu.Popa set files: + issue23078.patchcomponents: + Library (Lib), - Testskeywords: + patchnosy: + Claudiu.Popamessages: + stage: patch review
2014-12-18 08:45:23 kevinbenton create