Issue 26704: unittest.mock.patch: Double patching instance method: AttributeError: Mock object has no attribute 'name' (original) (raw)

Issue26704

Created on 2016-04-06 20:01 by asottile, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
patch asottile,2016-04-06 21:17 review
patch2 asottile,2016-04-06 23:32 review
2.patch Anthony Sottile,2016-05-01 21:48 review
Pull Requests
URL Status Linked Edit
PR 11085 merged Anthony Sottile,2018-12-10 21:22
PR 11126 merged miss-islington,2018-12-12 09:00
Messages (9)
msg262960 - (view) Author: Anthony Sottile (asottile) * Date: 2016-04-06 20:01
Originally from https://github.com/testing-cabal/mock/issues/350 ## Example ```python from unittest import mock class C(object): def f(self): pass c = C() with mock.patch.object(c, 'f', autospec=True): with mock.patch.object(c, 'f', autospec=True): pass ``` ## Python3.3 ``` $ test.py $ ``` ## Python3.4 / 3.5 / 3.6 (From gitbhub.com/python/cpython@fa3fc6d7) ``` Traceback (most recent call last): File "test.py", line 10, in with mock.patch.object(c, 'f', autospec=True): File "/home/asottile/workspace/cpython/Lib/unittest/mock.py", line 1320, in __enter__ _name=self.attribute, **kwargs) File "/home/asottile/workspace/cpython/Lib/unittest/mock.py", line 2220, in create_autospec _check_signature(original, new, skipfirst=skipfirst) File "/home/asottile/workspace/cpython/Lib/unittest/mock.py", line 112, in _check_signature _copy_func_details(func, checksig) File "/home/asottile/workspace/cpython/Lib/unittest/mock.py", line 117, in _copy_func_details funcopy.__name__ = func.__name__ File "/home/asottile/workspace/cpython/Lib/unittest/mock.py", line 578, in __getattr__ raise AttributeError("Mock object has no attribute %r" % name) AttributeError: Mock object has no attribute '__name__' ```
msg262966 - (view) Author: Anthony Sottile (asottile) * Date: 2016-04-06 21:17
The root cause seems to be that autospecced functions return a function object (not a Mock instance) which a '.mock' attribute which is a MagicMock ( assigned here: https://github.com/python/cpython/blob/ae775ab1eb72f42de2d070158bade4bf261ac04f/Lib/unittest/mock.py#L198 ) I took a first stab at a patch (attached)
msg262972 - (view) Author: Anthony Sottile (asottile) * Date: 2016-04-06 23:32
Here's an improved patch which: - passes the tests - puts the test in the correct place I'm not entirely happy with the approach -- open to suggestions :)
msg264611 - (view) Author: Anthony Sottile (Anthony Sottile) * Date: 2016-05-01 21:48
Seems I've named the patchfile incorrectly -- Hopefully this is correct this time?
msg331430 - (view) Author: Karthikeyan Singaravelan (xtreak) * (Python committer) Date: 2018-12-09 12:56
Thanks @asottile for the patch. I think the original AttributeError is resolved with where they were silenced. It seems similar to though the exception occurs from mock instead of partial object as in . The fix was applied to 3.7+ and hence 3.6 was not fixed which enters security fix only mode shortly. The attached tests also pass on master and I think it will it be a good unittest addition to Lib/unittest/test/testmock/testwith.py (similar to ) that has a couple of nested with statements for the same attribute. Adding cjw296 to the list.
msg331536 - (view) Author: Anthony Sottile (Anthony Sottile) * Date: 2018-12-10 21:23
I've opened a PR with the test included: https://github.com/python/cpython/pull/11085
msg331579 - (view) Author: Chris Withers (cjw296) * (Python committer) Date: 2018-12-11 06:23
Before we get too far: what's the use case for this double patching?
msg331588 - (view) Author: Anthony Sottile (Anthony Sottile) * Date: 2018-12-11 06:55
to be honest, I don't recall exactly given it's been 2 and a half years since the original report with no activity. if I recall correctly, this was encountered while upgrading the `mock` backport in yelp's monolithic repository. I want to say the reason this was hard to "fix" properly was due to some blanket patches being applied in a base test case and then other test cases re-patching those methods to add more specific behaviour. This worked fine in python2.7 and all the way until python3.3 but then was broken by changes in python3.4 Fortunately, they've been fixed in python3.7. I guess I've been encouraged to write a patch with a test so it does not regress in the future
msg331590 - (view) Author: Chris Withers (cjw296) * (Python committer) Date: 2018-12-11 07:09
Ah, yeah, I can see the blanket patch and a more local patch in a monorepo being a thing, cool, let's have a look!
History
Date User Action Args
2022-04-11 14:58:29 admin set github: 70891
2018-12-12 09:01:53 cjw296 set status: open -> closedresolution: fixedstage: patch review -> resolved
2018-12-12 09:00:26 miss-islington set pull_requests: + <pull%5Frequest10358>
2018-12-11 07:09:29 cjw296 set messages: +
2018-12-11 06:55:45 Anthony Sottile set messages: +
2018-12-11 06:23:47 cjw296 set messages: +
2018-12-10 21:23:00 Anthony Sottile set messages: +
2018-12-10 21:22:31 Anthony Sottile set pull_requests: + <pull%5Frequest10317>
2018-12-09 12:56:47 xtreak set nosy: + cjw296, xtreakmessages: +
2016-05-01 21:48:00 Anthony Sottile set files: + 2.patchnosy: + Anthony Sottilemessages: + keywords: + patch
2016-04-07 14:50:00 SilentGhost set nosy: + michael.foordstage: patch reviewtype: crash -> behaviorversions: - Python 3.4
2016-04-06 23:32:02 asottile set files: + patch2messages: +
2016-04-06 21:17:51 asottile set files: + patchmessages: +
2016-04-06 20:01:26 asottile create