This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Importing call from unittest.mock directly causes ValueError
Type: behavior Stage: resolved
Components: Tests Versions: Python 3.11, Python 3.10
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: Thomas Hisch, lukasz.langa, miss-islington, pablogsal, splbio, toonarmycaptain, xtreak
Priority: normal Keywords: patch

Created on 2019-01-16 20:17 by toonarmycaptain, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 22834 closed splbio, 2020-10-20 20:27
PR 22981 merged splbio, 2020-10-26 03:03
PR 25926 merged miss-islington, 2021-05-05 17:33
Messages (14)
msg333786 - (view) Author: David Antonini (toonarmycaptain) * Date: 2019-01-16 20:17
Ok so that's a pretty odd bug. I already had from unittest.mock import patch, mock_open so I simply modified that to from  instead of doing mock.call in my test. Changing this to from unittest import mock and then mock.call fixed the error.

from unittest.mock import patch, mock_open, call

mocked_print.assert_has_calls([
    call("first print"),
    call("second print"),
    ])

I get: 

C:\Program Files (x86)\Python37-64\lib\doctest.py:932: in find
    self._find(tests, obj, name, module, source_lines, globs, {})
C:\Program Files (x86)\Python37-64\lib\doctest.py:991: in _find
    if ((inspect.isroutine(inspect.unwrap(val))
C:\Program Files (x86)\Python37-64\lib\inspect.py:515: in unwrap
    raise ValueError('wrapper loop when unwrapping {!r}'.format(f))
E   ValueError: wrapper loop when unwrapping call
collected 1 item / 1 errors

But when I don't import call directly my test runs as expected:

from unittest.mock import patch, mock_open

import unittest.mock

mocked_print.assert_has_calls([
    mock.call(),
    mock.call(),
    ])

I have the same issue when using:

assert mocked_print.call_args_list == [call("first print"), call("second print")] <- ValueError
assert mocked_print.call_args_list == [mock.call("first print"), mock.call("second print")] <- Works as expected.
msg333787 - (view) Author: David Antonini (toonarmycaptain) * Date: 2019-01-16 20:19
I'm having a problem with mock.call when I import it directly from unittest.mock.

When I do:

from unittest.mock import patch, mock_open, call

mocked_print.assert_has_calls([
    call("first print"),
    call("second print"),
    ])

I get: 

C:\Program Files (x86)\Python37-64\lib\doctest.py:932: in find
    self._find(tests, obj, name, module, source_lines, globs, {})
C:\Program Files (x86)\Python37-64\lib\doctest.py:991: in _find
    if ((inspect.isroutine(inspect.unwrap(val))
C:\Program Files (x86)\Python37-64\lib\inspect.py:515: in unwrap
    raise ValueError('wrapper loop when unwrapping {!r}'.format(f))
E   ValueError: wrapper loop when unwrapping call
collected 1 item / 1 errors

But when I don't import call directly my test runs as expected:

from unittest.mock import patch, mock_open

import unittest.mock

mocked_print.assert_has_calls([
    mock.call(),
    mock.call(),
    ])

I have the same issue when using:

assert mocked_print.call_args_list == [call("first print"), call("second print")] <- ValueError
assert mocked_print.call_args_list == [mock.call("first print"), mock.call("second print")] <- Works as expected.
msg333788 - (view) Author: David Antonini (toonarmycaptain) * Date: 2019-01-16 20:21
Apologies for initial malformed message, I hit submit prematurely.
msg333789 - (view) Author: Pablo Galindo Salgado (pablogsal) * (Python committer) Date: 2019-01-16 20:32
Hi David,

Can you provide a full reproducer? In your example, mocked_print is undefined. Please, provide a self-contained script that can be executed to test the behaviour.
msg333790 - (view) Author: (ppperry) Date: 2019-01-16 20:48
According to the error message, this is a duplicate of https://bugs.python.org/issue25532
msg333791 - (view) Author: Pablo Galindo Salgado (pablogsal) * (Python committer) Date: 2019-01-16 21:27
Indeed, closed as duplicate of https://bugs.python.org/issue25532
msg333797 - (view) Author: (ppperry) Date: 2019-01-16 22:18
Sorry, looks like I was wrong about it being a duplicate. The actual bug appears to be "doctest can't run on a module that contains un-unwrappable objects", which there probably is an issue for but I don't know what it is.
msg343335 - (view) Author: Thomas Hisch (Thomas Hisch) Date: 2019-05-24 01:12
I think this tickt needs to be reopened, because

> The actual bug appears to be "doctest can't run on a module that contains un-unwrappable objects"

@ppperry Or do you already know where this issue is tracked?
msg343339 - (view) Author: (ppperry) Date: 2019-05-24 03:09
Indeed, you are right that this should be reopened.
msg343573 - (view) Author: Karthikeyan Singaravelan (xtreak) * (Python committer) Date: 2019-05-26 17:54
> The actual bug appears to be "doctest can't run on a module that contains un-unwrappable objects"

Is it the below example scenario being discussed in the issue? Since call is imported it's also present in obj.__dict__ and hence trying to unwrap it [0] could cause error.

This is also mentioned in https://bugs.python.org/issue25532#msg253885 against which this issue was closed. 

> This can occur when you use doctest.DocTestSuite to load doc tests from a module where unittest.mock.call has been imported.

# bpo35753.py
from unittest.mock import call

./python.exe -m doctest bpo35753.py
Traceback (most recent call last):
  File "/Users/karthikeyansingaravelan/stuff/python/cpython/Lib/runpy.py", line 192, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/Users/karthikeyansingaravelan/stuff/python/cpython/Lib/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/Users/karthikeyansingaravelan/stuff/python/cpython/Lib/doctest.py", line 2785, in <module>
    sys.exit(_test())
  File "/Users/karthikeyansingaravelan/stuff/python/cpython/Lib/doctest.py", line 2775, in _test
    failures, _ = testmod(m, verbose=verbose, optionflags=options)
  File "/Users/karthikeyansingaravelan/stuff/python/cpython/Lib/doctest.py", line 1947, in testmod
    for test in finder.find(m, name, globs=globs, extraglobs=extraglobs):
  File "/Users/karthikeyansingaravelan/stuff/python/cpython/Lib/doctest.py", line 932, in find
    self._find(tests, obj, name, module, source_lines, globs, {})
  File "/Users/karthikeyansingaravelan/stuff/python/cpython/Lib/doctest.py", line 991, in _find
    if ((inspect.isroutine(inspect.unwrap(val))
  File "/Users/karthikeyansingaravelan/stuff/python/cpython/Lib/inspect.py", line 524, in unwrap
    raise ValueError('wrapper loop when unwrapping {!r}'.format(f))
ValueError: wrapper loop when unwrapping call


[0] https://github.com/python/cpython/blob/aaf47caf35984e614d93bd8bea5227df55e0e3e6/Lib/doctest.py#L991
msg379177 - (view) Author: David Antonini (toonarmycaptain) * Date: 2020-10-21 01:00
Somehow I missed the follow up here until now. I don't remember the original code, but I'm fairly confident that mocked_print is the patched print function eg 
with patch('dionysus_app.class_functions.print') as mocked_print:

Probably solved in this commit dated the same day as the bug report:
https://github.com/toonarmycaptain/dionysus/commit/4f0eb7ca32b891d99106441b92a6c1accd0bb96d
msg388710 - (view) Author: Alfred Perlstein (splbio) * Date: 2021-03-15 06:14
I have a patch here that fixes this: https://github.com/python/cpython/pull/22981

It simply swallows the unwrap exception making doctest immune to such buggy objects.

Can someone help it get reviewed please?
msg393027 - (view) Author: Łukasz Langa (lukasz.langa) * (Python committer) Date: 2021-05-05 18:01
New changeset 10d6f6bfd749c0e7da51a96f53ca326c336f7a00 by Miss Islington (bot) in branch '3.10':
bpo-35753: Fix crash in doctest with unwrap-able functions (GH-22981) (#25926)
https://github.com/python/cpython/commit/10d6f6bfd749c0e7da51a96f53ca326c336f7a00
msg393028 - (view) Author: Łukasz Langa (lukasz.langa) * (Python committer) Date: 2021-05-05 18:02
Fixed in 3.10 and 3.11, thanks Albert for your patch.
History
Date User Action Args
2022-04-11 14:59:10adminsetgithub: 79934
2021-07-18 15:30:41pablogsalsetpull_requests: - pull_request25778
2021-07-18 15:26:31pablogsalsetpull_requests: + pull_request25778
2021-05-05 18:02:39lukasz.langasetstatus: open -> closed
versions: + Python 3.10, Python 3.11, - Python 3.7
messages: + msg393028

resolution: fixed
stage: patch review -> resolved
2021-05-05 18:01:44lukasz.langasetnosy: + lukasz.langa
messages: + msg393027
2021-05-05 17:33:26miss-islingtonsetnosy: + miss-islington
pull_requests: + pull_request24593
2021-03-15 06:14:35splbiosetmessages: + msg388710
2020-10-26 03:03:22splbiosetpull_requests: + pull_request21898
2020-10-21 01:00:20toonarmycaptainsetmessages: + msg379177
2020-10-20 20:27:53splbiosetkeywords: + patch
nosy: + splbio

pull_requests: + pull_request21788
stage: resolved -> patch review
2019-05-26 21:15:04ppperrysetnosy: - ppperry
2019-05-26 17:54:02xtreaksetmessages: + msg343573
2019-05-26 17:26:18pablogsalsetstatus: closed -> open
resolution: duplicate -> (no value)
2019-05-24 03:28:35xtreaksetnosy: + xtreak
2019-05-24 03:09:23ppperrysetmessages: + msg343339
2019-05-24 01:12:07Thomas Hischsetnosy: + Thomas Hisch
messages: + msg343335
2019-01-16 22:18:14ppperrysetmessages: + msg333797
2019-01-16 21:27:39pablogsalsetstatus: open -> closed
resolution: duplicate
messages: + msg333791

stage: resolved
2019-01-16 20:48:34ppperrysetnosy: + ppperry
messages: + msg333790
2019-01-16 20:32:54pablogsalsetnosy: + pablogsal
messages: + msg333789
2019-01-16 20:21:29toonarmycaptainsetmessages: + msg333788
2019-01-16 20:19:08toonarmycaptainsetmessages: + msg333787
2019-01-16 20:17:24toonarmycaptaincreate