[issue26140] inspect.iscoroutinefunction raises TypeError when checks Mock of function or coroutinefunction
New submission from Hiroyuki Takagi: inspect.iscoroutinefunction and asyncio.iscoroutinefunction with patch of issue25599 (https://bugs.python.org/issue25599) raise TypeError when used to check Mock object which mocks function or coroutinefunction. How to reproduce: - For the mock of function >>> from unittest.mock import Mock >>> import inspect >>> def a():... ... >>> inspect.iscoroutinefunction(Mock(a)) Expected: False Actual: Traceback (most recent call last): File "", line 1, in File ".../cpython/Lib/inspect.py", line 187, in iscoroutinefunction object.__code__.co_flags & CO_COROUTINE) TypeError: unsupported operand type(s) for &: 'Mock' and 'int' - For the mock of coroutine-function >>> async def b():... ... >>> inspect.iscoroutinefunction(Mock(b)) Expected: True Actual: Traceback (most recent call last): File "", line 1, in File ".../cpython/Lib/inspect.py", line 187, in iscoroutinefunction object.__code__.co_flags & CO_COROUTINE) TypeError: unsupported operand type(s) for &: 'Mock' and 'int' Without the patch of issue25599, asyncio.iscoroutinefunction does not raise error and returns Mock object. But I don't think it is expected behavior, as discussed in that issue. I wrote a patch to solve this problem. -- components: asyncio files: mock.patch keywords: patch messages: 258464 nosy: gvanrossum, haypo, miyakogi, yselivanov priority: normal severity: normal status: open title: inspect.iscoroutinefunction raises TypeError when checks Mock of function or coroutinefunction type: behavior versions: Python 3.5 Added file: http://bugs.python.org/file41638/mock.patch ___ Python tracker <http://bugs.python.org/issue26140> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue26140] inspect.iscoroutinefunction raises TypeError when checks Mock of function or coroutinefunction
Hiroyuki Takagi added the comment: Thank you for review and comment. Honestly speaking, I couldn't find any other good place to fix it. One possible solution might be to use isinstance(mock, Mock) in iscoroutinefunction, but I don't think it's good for inspect module to add special check and depend on unittest.mock. Mocks are usually used only in debug/test, but iscoroutinefunction is used in production code. Adding some check to iscoroutinefunction only for test is not good for performance (though, actually its effect will be very small). The reasons why I think this behavior should be fixed are, - Raising error and stopping test is not kind for mock users - After the patch (issue25599), no mock object can become `True` to iscoroutinefunction, which will make it impossible to test the block after if-iscoroutinefunction by using mock. Now, I checked inspect module again, and found one more unexpected behavior (not error). >>> def a(): yield 1 >>> inspect.isgeneratorfunction(a) True >>> inspect.isgeneratorfunction(Mock(a)) False With the patch, inspect.isgeneratorfunction(Mock(a)) returns True. -- ___ Python tracker <http://bugs.python.org/issue26140> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue26140] inspect.iscoroutinefunction raises TypeError when checks Mock of function or coroutinefunction
Hiroyuki Takagi added the comment: Thank you for reviewing patch. I wrote test and updated patch. To pass the test, both this patch and issue25599's patch are required. Changes of the patch: - copy __code__ not only functions but also methods - add autospec (create_autospec) suppoort I have completely missed about autospec, thank you for a mention about it. For autospec, simply copying original __code__ to funcopy makes error on existing tests. That's why I changed the src of exec, but it seems to be quite ad-hoc. It may be better to be improved, but I don't have any good idea, sorry. On the tests of this patch, I wonder if it's better to use assertIs(.., True/False) instead of assertTrue/False, since it was one of the problem in issue25599. To apply this change and pass test, need to change asyncio.iscoroutinefunction to return bool. The change would be very easy, just update issue25599's patch like `return_value = bool(getattr(func, ...`. -- Added file: http://bugs.python.org/file41664/mock2.patch ___ Python tracker <http://bugs.python.org/issue26140> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com