[V3 Config] Fix for unnecessary writes on context mgr exit (#1859)

* Fix for #1857

* And copy it so we don't have mutability issues

* Add a test
This commit is contained in:
Will 2018-06-22 22:15:22 -04:00 committed by Toby Harradine
parent afa08713e0
commit edadd8f2fd
2 changed files with 16 additions and 1 deletions

View File

@ -29,12 +29,15 @@ class _ValueCtxManager:
def __init__(self, value_obj, coro): def __init__(self, value_obj, coro):
self.value_obj = value_obj self.value_obj = value_obj
self.coro = coro self.coro = coro
self.raw_value = None
self.__original_value = None
def __await__(self): def __await__(self):
return self.coro.__await__() return self.coro.__await__()
async def __aenter__(self): async def __aenter__(self):
self.raw_value = await self self.raw_value = await self
self.__original_value = deepcopy(self.raw_value)
if not isinstance(self.raw_value, (list, dict)): if not isinstance(self.raw_value, (list, dict)):
raise TypeError( raise TypeError(
"Type of retrieved value must be mutable (i.e. " "Type of retrieved value must be mutable (i.e. "
@ -44,7 +47,8 @@ class _ValueCtxManager:
return self.raw_value return self.raw_value
async def __aexit__(self, *exc_info): async def __aexit__(self, *exc_info):
await self.value_obj.set(self.raw_value) if self.raw_value != self.__original_value:
await self.value_obj.set(self.raw_value)
class Value: class Value:

View File

@ -1,3 +1,4 @@
from unittest.mock import patch
import pytest import pytest
@ -399,6 +400,16 @@ async def test_ctxmgr_no_shared_default(config, member_factory):
assert 1 not in await config.member(m2).foo() assert 1 not in await config.member(m2).foo()
@pytest.mark.asyncio
async def test_ctxmgr_no_unnecessary_write(config):
config.register_global(foo=[])
foo_value_obj = config.foo
with patch.object(foo_value_obj, "set") as set_method:
async with foo_value_obj() as foo:
pass
set_method.assert_not_called()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_get_then_mutate(config): async def test_get_then_mutate(config):
"""Tests that mutating an object after getting it as a value doesn't mutate the data store.""" """Tests that mutating an object after getting it as a value doesn't mutate the data store."""