[issue42159] AsyncMock restores stopped patch if same object stopped multiple times

2020-10-27 Thread Karthikeyan Singaravelan


Karthikeyan Singaravelan  added the comment:

This is not a problem with AsyncMock. The patching is not done when the patch 
object is created to store reference to the original unpatched function. Hence 
patcher1, patcher2 that patch the same function don't store a reference to the 
original sync_func. The lookup is done during start(). patcher1.start() makes a 
lookup and stores the function. When patcher2.start() makes a lookup the 
function is already patched with a mock and thus it resorts to the original as 
the mock. 

When stop is called on patcher1 it resets back to the original function. 
Meanwhile for patcher2 the original function set during start itself is a mock 
and it resets back to that. The lookup is done at 
https://github.com/python/cpython/blob/a6879d9445f98833c4e300e187956e2a218a2315/Lib/unittest/mock.py#L1360
 . Here target will print the function for patcher1.start() but the mock for 
patcher2.start().

import asyncio
import unittest
from unittest import TestCase
from unittest.mock import *

def sync_func():
raise Exception

class Test(TestCase):

def test_simultaneous_mocks_sync(self):
patcher1 = patch(f"{__name__}.sync_func")
patcher2 = patch(f"{__name__}.sync_func")

patcher1.start()
print(sync_func())

patcher2.start()
print(sync_func())

breakpoint()
patcher1.stop()
with self.assertRaises(Exception):
sync_func()

breakpoint()
patcher2.stop()

with self.assertRaises(Exception): # Fails, mock is restored!
sync_func()

if __name__ == "__main__":
unittest.main()

--
components: +Library (Lib)
type:  -> behavior

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue42159] AsyncMock restores stopped patch if same object stopped multiple times

2020-10-27 Thread Karthikeyan Singaravelan


Change by Karthikeyan Singaravelan :


--
nosy: +xtreak

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue42159] AsyncMock restores stopped patch if same object stopped multiple times

2020-10-26 Thread Lisa Roach


New submission from Lisa Roach :

Hard to explain in the title, easier to see via a test case:

 async def async_func():
 raise Exception

def test_simultaneous_mocks(self):
class Test(IsolatedAsyncioTestCase):
async def test_test(self):
patcher1 = patch(f"{__name__}.async_func")
patcher2 = patch(f"{__name__}.async_func")
patcher1.start()
await async_func()
patcher2.start()
await async_func()
patcher1.stop()
with self.assertRaises(Exception):
await async_func()
patcher2.stop()
with self.assertRaises(Exception): # Fails, mock is restored!
await async_func()

test = Test("test_test")
output = test.run()
self.assertTrue(output.wasSuccessful()) # Fail


Calling stop() on the second patch actually restores the mock and causes the 
test to fail.

--
assignee: lisroach
messages: 379687
nosy: lisroach
priority: normal
severity: normal
status: open
title: AsyncMock restores stopped patch if same object stopped multiple times
versions: Python 3.10, Python 3.8, Python 3.9

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com