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

asyncio.iscoroutinefunction returns unexpected results when presented with unittest.mock.Mock #69785

Closed
luhn mannequin opened this issue Nov 10, 2015 · 10 comments
Closed
Labels
topic-asyncio type-bug An unexpected behavior, bug, or error

Comments

@luhn
Copy link
Mannequin

luhn mannequin commented Nov 10, 2015

BPO 25599
Nosy @gvanrossum, @jcea, @vstinner, @1st1, @tirkarthi
Files
  • issue25599.patch
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = <Date 2019-06-12.18:13:27.441>
    created_at = <Date 2015-11-10.17:26:22.054>
    labels = ['type-bug', 'expert-asyncio']
    title = 'asyncio.iscoroutinefunction returns unexpected results when presented with unittest.mock.Mock'
    updated_at = <Date 2019-06-12.18:13:27.434>
    user = 'https://bugs.python.org/luhn'

    bugs.python.org fields:

    activity = <Date 2019-06-12.18:13:27.434>
    actor = 'xtreak'
    assignee = 'none'
    closed = True
    closed_date = <Date 2019-06-12.18:13:27.441>
    closer = 'xtreak'
    components = ['asyncio']
    creation = <Date 2015-11-10.17:26:22.054>
    creator = 'luhn'
    dependencies = []
    files = ['41396']
    hgrepos = []
    issue_num = 25599
    keywords = ['patch']
    message_count = 10.0
    messages = ['254457', '254459', '254464', '254491', '254543', '256865', '256867', '256868', '256903', '345397']
    nosy_count = 7.0
    nosy_names = ['gvanrossum', 'jcea', 'vstinner', 'yselivanov', 'josephgordon', 'luhn', 'xtreak']
    pr_nums = []
    priority = 'normal'
    resolution = 'fixed'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue25599'
    versions = ['Python 3.2', 'Python 3.3', 'Python 3.4', 'Python 3.5', 'Python 3.6']

    @luhn
    Copy link
    Mannequin Author

    luhn mannequin commented Nov 10, 2015

    >>> asyncio.iscoroutinefunction(unittest.mock.Mock())
    <Mock name='mock._is_coroutine' id='4544068072'>

    This is an unexpected response, both in type (Mock rather than boolean) and value (truthy).

    inspect.iscoroutinefunction behaves as expected.

    Workaround:

    >>> m = unittest.mock.Mock()
    >>> m._is_coroutine = False
    >>> asyncio.iscoroutinefunction(m)
    False

    @luhn luhn mannequin added topic-asyncio type-bug An unexpected behavior, bug, or error labels Nov 10, 2015
    @gvanrossum
    Copy link
    Member

    Hm... I don't know what answer you would expect. Who says your mock shouldn't behave like a coroutine? In general, passing mocks to functions is likely to return a mock -- even boolean functions.

    Can you provide more context?

    @vstinner
    Copy link
    Member

    >>> asyncio.iscoroutinefunction(unittest.mock.Mock())
    <Mock name='mock._is_coroutine' id='4544068072'>

    Yeah, I already had this issue when I wrote unit tests using mock :-/ I didn't find an obvious fix for this issue, and it's quite easy to workaround it.

    It looks like the "m._is_coroutine = False" is not used in asyncio tests. I don't recall how I worked around the issue in asyncio tests...

    @luhn
    Copy link
    Mannequin Author

    luhn mannequin commented Nov 11, 2015

    For me, the context is a test I was writing that went something like this:

    >>> import asyncio
    >>> from unittest.mock import Mock
    >>> loop = asyncio.get_event_loop()
    >>> blocking_func = Mock()
    >>> loop.run_in_executor(None, blocking_func)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/usr/local/Cellar/python3/3.5.0/Frameworks/Python.framework/Versions/3.5/lib/python3.5/asyncio/base_events.py", line 497, in run_in_executor
        raise TypeError("coroutines cannot be used with run_in_executor()")
    TypeError: coroutines cannot be used with run_in_executor()

    I understand that the nature of Mock makes its behaviors ambiguous. However, there are a few reasons I think asyncio.iscoroutinefunction(Mock()) should be false:

    1. inspect.iscoroutinefunction reports false. asyncio.iscoroutinefunction should be consistent with this.
    2. A coroutine function should return a coroutine object. Mock's default behavior won't return a coroutine object, so it shouldn't be identified as a coroutine function by default.
    3. It's tidier to make a non-coroutine function Mock into a coroutine function (asyncio.coroutine(Mock())) than it is to make a coroutine function Mock into a non-coroutine function Mock (mock._is_coroutine is implementation-specific hack).

    @gvanrossum
    Copy link
    Member

    OK, I concede your point. It shouldn't be too hard to make
    asyncio.iscoroutinefunction() behave the same way as
    inspect.iscoroutinefunction(). Can you submit a patch?

    @gvanrossum
    Copy link
    Member

    Oh dang. We were waiting for the OP to submit a patch (not very complex)
    but they never did. Now we missed the 3.5.2 deadline. Maybe someone can try
    again for 3.5.3?

    On Tue, Dec 22, 2015 at 12:30 AM, Joseph Gordon <report@bugs.python.org>
    wrote:

    Changes by Joseph Gordon <j.gordon.matthew@gmail.com>:

    ----------
    nosy: +josephgordon


    Python tracker <report@bugs.python.org>
    <http://bugs.python.org/issue25599\>


    @1st1
    Copy link
    Member

    1st1 commented Dec 22, 2015

    Now we missed the 3.5.2 deadline.

    Did you mean 3.5.1? Or Larry is going to rush 3.5.2 soon?

    @gvanrossum
    Copy link
    Member

    No I just misremembered.

    --Guido (mobile)

    @josephgordon
    Copy link
    Mannequin

    josephgordon mannequin commented Dec 23, 2015

    I uploaded a patch that appears to fix the issue.

    @tirkarthi
    Copy link
    Member

    I guess the inconsistency in original report is fixed with bpo-28703 where both inspect.iscoroutinefunction and asyncio.iscoroutinefunction return False for Mock(). The fix is available from 3.5.3 . There is also async support for mock added in 3.8 with bpo-26467. I am closing this as part of triaging. Feel free to reopen this if I am missing something. Thanks.

    # Python 3.5

    python3.5
    Python 3.5.2 (default, Nov 12 2018, 13:43:14)
    [GCC 5.4.0 20160609] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import asyncio
    >>> from unittest.mock import *
    >>> asyncio.iscoroutinefunction(Mock())
    <Mock name='mock._is_coroutine' id='140563339256496'>

    # Master

    ./python.exe
    Python 3.9.0a0 (heads/master:daf6262751, Jun 12 2019, 23:12:37)
    [Clang 7.0.2 (clang-700.1.81)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> from unittest.mock import Mock
    >>> import asyncio, inspect
    >>> inspect.iscoroutinefunction(Mock())
    False
    >>> asyncio.iscoroutinefunction(Mock())
    False

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    topic-asyncio type-bug An unexpected behavior, bug, or error
    Projects
    None yet
    Development

    No branches or pull requests

    4 participants