def test_param_cache_reload(dynamic): class BackgroundConfig(byoc.Config): def load(self): yield byoc.DictLayer(values={'x': -1}) class ForegroundConfig(byoc.Config): values = {'x': 1} def load(self): # Access the value of the parameter during the load function so # that we can tell if an intermediate value from the loading # process (e.g. -1) is mistakenly saved as the cache value. self.obj.x yield byoc.DictLayer(values=self.values) class DummyObj: __config__ = [ForegroundConfig, BackgroundConfig] x = byoc.param(dynamic=dynamic) obj = DummyObj() assert obj.x == 1 # Before updating the cache: ForegroundConfig.values['x'] = 2 assert obj.x == (2 if dynamic else 1) # After updating the cache: byoc.reload(obj) assert obj.x == 2
def test_reload_instead_of_init(): class DummyConfig(byoc.Config): def __init__(self, obj): super().__init__(obj) self.x = 0 def load(self): self.x += 1 yield byoc.DictLayer({'x': self.x}) class DummyObj: __config__ = [DummyConfig] x = byoc.param() obj = DummyObj() byoc.reload(obj) assert obj.x == 1 byoc.reload(obj) assert obj.x == 2
def test_init_load_reload(obj, init_layers, load_layers, reload_layers): if not reload_layers: reload_layers = load_layers byoc.init(obj) assert collect_layers(obj) == init_layers try: obj.load() except AttributeError: byoc.load(obj) assert collect_layers(obj) == load_layers try: obj.reload() except AttributeError: byoc.reload(obj) assert collect_layers(obj) == reload_layers
def test_param_cache_exc(dynamic): # Make sure exceptions are cached just like values are. class DummyConfig(byoc.Config): def load(self): yield byoc.DictLayer(self.obj.values) class DummyObj: __config__ = [DummyConfig] x = byoc.param(dynamic=dynamic) obj = DummyObj() # Before providing a value: obj.values = {} assert not hasattr(obj, 'x') # After providing a value, before updating the cache: obj.values['x'] = 1 assert (obj.x == 1) if dynamic else not hasattr(obj, 'x') # After updating the cache: byoc.reload(obj) assert obj.x == 1
def test_share_configs_mutable(): class DummyConfigA(byoc.Config): def load(self): yield byoc.DictLayer(self.obj.a, location='a') class DummyConfigB(byoc.Config): def load(self): yield byoc.DictLayer(self.obj.b, location='b') class DummyDonor: __config__ = [DummyConfigB] class DummyAcceptor: __config__ = [DummyConfigA] donor = DummyDonor() donor.a = {'x': 1} # decoy donor.b = {'x': 2} acceptor = DummyAcceptor() acceptor.a = {'x': 3} acceptor.b = {'x': 4} # decoy byoc.load(donor) byoc.load(acceptor) assert collect_layers(donor) == { 0: [ DictLayerWrapper({'x': 2}, location='b'), ], } assert collect_layers(acceptor) == { 0: [ DictLayerWrapper({'x': 3}, location='a'), ], } byoc.share_configs(donor, acceptor) byoc.reload(donor) byoc.reload(acceptor) assert collect_layers(donor) == { 0: [ DictLayerWrapper({'x': 2}, location='b'), ], } assert collect_layers(acceptor) == { 0: [ DictLayerWrapper({'x': 3}, location='a'), ], 1: [ DictLayerWrapper({'x': 2}, location='b'), ], } # Reloading donor updates acceptor: donor.b = {'x': 5} byoc.reload(donor) assert collect_layers(donor) == { 0: [ DictLayerWrapper({'x': 5}, location='b'), ], } assert collect_layers(acceptor) == { 0: [ DictLayerWrapper({'x': 3}, location='a'), ], 1: [ DictLayerWrapper({'x': 5}, location='b'), ], }