Async Patching issue with static methods in Python

I’m having a problem trying to patch a static method, no matter what i’ve tried the original method is still being ran. I’ll illustrate an example below.

file A

import B
from unittest.mock import patch
from unittest import mock
import asynctest
import unittest

class Test(asynctest.TestCase):
    @patch('B.OT._func')
    async def test(self, mock_func):
        mock_func.return_value = mock.MagicMock()
        await B.foo()
        mock_func.assert_called_once()
if __name__ == '__main__':
    unittest.main()

file B

from path.C import OT
  
async def foo():
    print('B')
    return OT._func()

path(folder)/file C

class OT:
    @staticmethod
    def _func():
        print('c')
        return True

Problem

I’m having issues mocking the return value for OT._func(). Whatever I try to patch in file A doesn’t stop _func() from running in class B. If the test case is ran it prints out ‘c’ instead of patching the function. My desired outcome is to patch out _func and have it return something else.

Edit: The issue seems to be with the async portion of the test, if the async is removed it works. A workaround for now is using the context manager version (with keyword) to patch stuff.

Answer

After looking into it more it seems to be an issue with async and the ‘@patch’ decorator specifically (and possible python 3.7). A simple workaround is to using patching alongside the ‘with’ keyword. This will bypass the patch decorator not working for async functions.

Alternatively, upgrading from python 3.7.2 to 3.8.2 also fixed the issue and allows patch decorators to work with async functions.