Movatterモバイル変換


[0]ホーム

URL:


homepage

Issue18622

This issue trackerhas been migrated toGitHub, and is currentlyread-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title:reset_mock on mock created by mock_open causes infinite recursion
Type:behaviorStage:needs patch
Components:Library (Lib)Versions:Python 3.6, Python 3.4, Python 3.5
process
Status:closedResolution:fixed
Dependencies:Superseder:
Assigned To: rbcollinsNosy List: Laurent.De.Buyst, berker.peksag, flox, kushal.das, michael.foord, nicola.palumbo, python-dev, rbcollins
Priority:normalKeywords:easy, patch

Created on2013-08-01 21:04 bymichael.foord, last changed2022-04-11 14:57 byadmin. This issue is nowclosed.

Files
File nameUploadedDescriptionEdit
issue18622.patchnicola.palumbo,2013-09-09 09:58review
issue18622_2.patchLaurent.De.Buyst,2014-01-14 13:23review
Messages (11)
msg194119 -(view)Author: Michael Foord (michael.foord)*(Python committer)Date: 2013-08-01 21:04
As reported at:http://code.google.com/p/mock/issues/detail?id=209>>> from unittest import mock[107971 refs]>>> mock.mock_open<function mock_open at 0x10cff9d20>[107974 refs]>>> a = mock.mock_open()[109965 refs]>>> a.reset_mock()...
msg194166 -(view)Author: Michael Foord (michael.foord)*(Python committer)Date: 2013-08-02 08:59
The best way to solve this seems to be to track a set of visited ids (mocks we've reset) and not recurse into mocks we've already done. This is similar to the patch proposed on the google code issue - but not identical as that uses a list and has it as the default argument to reset_mock.
msg197357 -(view)Author: Nicola Palumbo (nicola.palumbo)*Date: 2013-09-09 09:58
Hi all,I've fixed the infinite recursion in `reset_mock()`. It has been solved by tracking a set of visited ids as suggested.>>> from unittest import mock>>> a = mock.mock_open()>>> a.reset_mock()>>> a<MagicMock name='open' spec='builtin_function_or_method' id='4449688192'>
msg208029 -(view)Author: Laurent De Buyst (Laurent.De.Buyst)Date: 2014-01-13 15:52
The proposed patch does solve the infinite recursion bug, but a different problem appears when resetting the same mock multiple times: it only works the first time.Using the patch as it stands:>>> from unittest.mock import mock_open>>> mo = mock_open()>>> a = mo()>>> mo.call_count1>>> mo.reset_mock()>>> mo.call_count0>>> b = mo()>>> mo.call_count1>>> mo.reset_mock()>>> mo.call_count1And here from a version with an added print(visited) statement:>>> from unittest.mock import mock_open>>> mo = mock_open()>>> a = mo()>>> mo.call_count1>>> mo.reset_mock()[][139803191795152][139803191795152, 139803181189008][139803191795152, 139803181189008, 139803213598416][139803191795152, 139803181189008, 139803213598416, 139803213652048][139803191795152, 139803181189008, 139803213598416, 139803213652048]>>> mo.call_count0>>> b = mo()>>> mo.call_count1>>> mo.reset_mock()[139803191795152, 139803181189008, 139803213598416, 139803213652048, 139803213598288]>>> mo.call_count1>>> mo.reset_mock(visited=[])[][139803191795152][139803191795152, 139803181189008][139803191795152, 139803181189008, 139803213598416][139803191795152, 139803181189008, 139803213598416, 139803213652048][139803191795152, 139803181189008, 139803213598416, 139803213652048]>>> mo.call_count0As you can see, for some reason I don't quite grasp, the 'visited' parameter persists across calls to reset_mock(), meaning that the very first call does indeed reset it but subsequent calls do not.As the last two calls show, one can force a reset by explicitly providing an empty list, but this is starting to become a change in API and not just a bugfix...
msg208092 -(view)Author: Laurent De Buyst (Laurent.De.Buyst)Date: 2014-01-14 12:56
Sorry Michael, I should have read your second comment more closely since you already pointed out that using a list as default argument is bad.It is, however, easily fixed by changing to this:def reset_mock(self, visited=None):    "Restore the mock object to its initial state."    if visited is None:        visited = []    if id(self) in visited:        return
msg208093 -(view)Author: Nicola Palumbo (nicola.palumbo)*Date: 2014-01-14 13:21
I should have read more carefully, too! Thanks to both.
msg208095 -(view)Author: Laurent De Buyst (Laurent.De.Buyst)Date: 2014-01-14 13:23
And here's an actual patch with the corrected code
msg219105 -(view)Author: Florent Xicluna (flox)*(Python committer)Date: 2014-05-25 21:26
I've been bitten by this issue with a custom psycopg2 mock.>>> cur = mock.Mock()>>> >>> cur.connection.cursor.return_value = cur>>> cur.reset_mock()RuntimeError: maximum recursion depth exceededthe patch looks ok, except the mix of tab and spaces :-)
msg246743 -(view)Author: Robert Collins (rbcollins)*(Python committer)Date: 2015-07-14 23:21
Applying this to 3.4 and up with a test.Laurent, it would be good to sign the CLA - since your change here is minimal and Nicola has, I'm just going ahead.
msg246745 -(view)Author: Roundup Robot (python-dev)(Python triager)Date: 2015-07-14 23:42
New changeset4c8cb603ab42 by Robert Collins in branch '3.4':- Issue#18622: unittest.mock.mock_open().reset_mock would recurse infinitely.https://hg.python.org/cpython/rev/4c8cb603ab42
msg246746 -(view)Author: Roundup Robot (python-dev)(Python triager)Date: 2015-07-14 23:51
New changesetc0ec61cf5a7d by Robert Collins in branch '3.5':- Issue#18622: unittest.mock.mock_open().reset_mock would recurse infinitely.https://hg.python.org/cpython/rev/c0ec61cf5a7dNew changeseta4fe32477df6 by Robert Collins in branch 'default':- Issue#18622: unittest.mock.mock_open().reset_mock would recurse infinitely.https://hg.python.org/cpython/rev/a4fe32477df6
History
DateUserActionArgs
2022-04-11 14:57:48adminsetgithub: 62822
2015-07-15 00:08:57rbcollinssetstatus: open -> closed
assignee:michael.foord ->rbcollins
resolution: fixed
2015-07-14 23:51:34python-devsetmessages: +msg246746
2015-07-14 23:42:41python-devsetnosy: +python-dev
messages: +msg246745
2015-07-14 23:21:13rbcollinssetmessages: +msg246743
2015-07-14 20:20:25rbcollinssetnosy: +rbcollins

versions: + Python 3.6
2014-05-25 21:26:32floxsetnosy: +flox
messages: +msg219105
2014-04-16 20:50:16michael.foordsetnosy: +kushal.das

versions: + Python 3.5, - Python 3.3
2014-02-01 09:22:23berker.peksagsetnosy: +berker.peksag
2014-01-14 13:23:25Laurent.De.Buystsetfiles: +issue18622_2.patch

messages: +msg208095
2014-01-14 13:21:46nicola.palumbosetmessages: +msg208093
2014-01-14 12:56:48Laurent.De.Buystsetmessages: +msg208092
2014-01-13 15:52:23Laurent.De.Buystsetnosy: +Laurent.De.Buyst
messages: +msg208029
2013-09-09 09:58:09nicola.palumbosetfiles: +issue18622.patch

nosy: +nicola.palumbo
messages: +msg197357

keywords: +patch
2013-08-02 08:59:19michael.foordsetmessages: +msg194166
2013-08-01 21:04:17michael.foordcreate
Supported byThe Python Software Foundation,
Powered byRoundup
Copyright © 1990-2022,Python Software Foundation
Legal Statements

[8]ページ先頭

©2009-2026 Movatter.jp