mirror of
https://github.com/Akkudoktor-EOS/EOS.git
synced 2026-10-09 07:56:40 +00:00
fix(cache): distinguish callables in the shared EMS cache
Include the function object in cache keys so methods of one interpolator cannot reuse a probability as a power value. Cover both call orders, keyword arguments, cache hits and separate closures with identical qualified names.
This commit is contained in:
@@ -228,6 +228,9 @@ def cache_energy_management(
|
||||
|
||||
cached_wrapper = cachebox.cached(
|
||||
cache=CacheEnergyManagementStore().cache,
|
||||
# This store is shared by all decorated callables, including methods
|
||||
# on the same instance. Arguments alone cannot identify their results.
|
||||
key_maker=lambda *args, **kwargs: cachebox.make_key(func, *args, **kwargs),
|
||||
callback=cache_energy_management_store_callback,
|
||||
)(wrapper)
|
||||
|
||||
|
||||
@@ -88,6 +88,55 @@ class TestCacheUntilUpdateDecorators:
|
||||
assert CacheEnergyManagementStore.hit_count == 1
|
||||
assert result1 == result2
|
||||
|
||||
@pytest.mark.parametrize("reverse", [False, True])
|
||||
@pytest.mark.parametrize("use_kwargs", [False, True])
|
||||
def test_methods_with_identical_arguments_keep_separate_results(
|
||||
self, cache_energy_management_store, reverse, use_kwargs
|
||||
):
|
||||
calls = []
|
||||
|
||||
class Model:
|
||||
@cache_energy_management
|
||||
def fraction(self, value):
|
||||
calls.append("fraction")
|
||||
return value / 1000
|
||||
|
||||
@cache_energy_management
|
||||
def energy(self, value):
|
||||
calls.append("energy")
|
||||
return value * 1000
|
||||
|
||||
model = Model()
|
||||
cases = [(model.fraction, 0.005), (model.energy, 5000)]
|
||||
if reverse:
|
||||
cases.reverse()
|
||||
for _ in range(2):
|
||||
for method, expected in cases:
|
||||
result = method(value=5) if use_kwargs else method(5)
|
||||
assert result == expected
|
||||
assert sorted(calls) == ["energy", "fraction"]
|
||||
assert CacheEnergyManagementStore.miss_count == 2
|
||||
assert CacheEnergyManagementStore.hit_count == 2
|
||||
|
||||
def test_distinct_closures_with_same_name_do_not_share_results(
|
||||
self, cache_energy_management_store
|
||||
):
|
||||
def make_function(factor):
|
||||
@cache_energy_management
|
||||
def compute(value):
|
||||
return value * factor
|
||||
return compute
|
||||
|
||||
double = make_function(2)
|
||||
triple = make_function(3)
|
||||
assert double.__qualname__ == triple.__qualname__
|
||||
assert double(4) == 8
|
||||
assert triple(4) == 12
|
||||
assert double(4) == 8
|
||||
assert triple(4) == 12
|
||||
assert CacheEnergyManagementStore.miss_count == 2
|
||||
assert CacheEnergyManagementStore.hit_count == 2
|
||||
|
||||
def test_cache_energy_management(self, cache_energy_management_store):
|
||||
"""Test that cache_energy_management caches function results."""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user