Skip to content

Commit

Permalink
Allow to set uncached variables when using a memory_config
Browse files Browse the repository at this point in the history
  • Loading branch information
fpagnoux authored Jul 11, 2018
2 parents 75766fb + 5d30d28 commit 8fff6dc
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 16 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

### 23.1.5 [#687](https://github.com/openfisca/openfisca-core/pull/687)

* Allow to set uncached variables when using a `memory_config`
- Previously, trying to set variables listed in `variables_to_drop` of the `memory_config` had no effect.
- Now this variables are still not cached, but they can be set by the user.

### 23.1.4 [#679](https://github.com/openfisca/openfisca-core/pull/679)

* Use C binding to load and dump Yaml (`CLoader` and `CDumper`)
Expand Down
31 changes: 16 additions & 15 deletions openfisca_core/holders.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,14 +178,9 @@ def set_input(self, period, array):
)
if self.variable.set_input:
return self.variable.set_input(self, period, array)
return self.put_in_cache(array, period)

def put_in_cache(self, value, period, extra_params = None):
if self._do_not_store:
return

simulation = self.simulation
return self._set(period, array)

def _set(self, period, value, extra_params = None):
if self.variable.value_type == Enum:
value = self.variable.possible_values.encode(value)

Expand All @@ -200,7 +195,7 @@ def put_in_cache(self, value, period, extra_params = None):

if self.variable.definition_period != ETERNITY:
if period is None:
raise ValueError('A period must be specified to put values in cache, except for variables with ETERNITY as as period_definition.')
raise ValueError('A period must be specified to set values, except for variables with ETERNITY as as period_definition.')
if ((self.variable.definition_period == MONTH and period.unit != periods.MONTH) or
(self.variable.definition_period == YEAR and period.unit != periods.YEAR)):
error_message = os.linesep.join([
Expand All @@ -221,11 +216,6 @@ def put_in_cache(self, value, period, extra_params = None):
error_message
)

if (simulation.opt_out_cache and
simulation.tax_benefit_system.cache_blacklist and
self.variable.name in simulation.tax_benefit_system.cache_blacklist):
return

should_store_on_disk = (
self._on_disk_storable and
self._memory_storage.get(period, extra_params) is None and # If there is already a value in memory, replace it and don't put a new value in the disk storage
Expand All @@ -237,6 +227,17 @@ def put_in_cache(self, value, period, extra_params = None):
else:
self._memory_storage.put(value, period, extra_params)

def put_in_cache(self, value, period, extra_params = None):
if self._do_not_store:
return

if (self.simulation.opt_out_cache and
self.simulation.tax_benefit_system.cache_blacklist and
self.variable.name in self.simulation.tax_benefit_system.cache_blacklist):
return

self._set(period, value, extra_params)

def default_array(self):
"""
Return a new array of the appropriate length for the entity, filled with the variable default values.
Expand Down Expand Up @@ -344,7 +345,7 @@ def set_input_dispatch_by_period(holder, period, array):
while sub_period.start < after_instant:
existing_array = holder.get_array(sub_period)
if existing_array is None:
holder.put_in_cache(array, sub_period)
holder._set(sub_period, array)
else:
# The array of the current sub-period is reused for the next ones.
# TODO: refactor or document this behavior
Expand Down Expand Up @@ -391,7 +392,7 @@ def set_input_divide_by_period(holder, period, array):
sub_period = period.start.period(cached_period_unit)
while sub_period.start < after_instant:
if holder.get_array(sub_period) is None:
holder.put_in_cache(divided_array, sub_period)
holder._set(sub_period, divided_array)
sub_period = sub_period.offset(1)
elif not (remaining_array == 0).all():
raise ValueError(u"Inconsistent input: variable {0} has already been set for all months contained in period {1}, and value {2} provided for {1} doesn't match the total ({3}). This error may also be thrown if you try to call set_input twice for the same variable and period.".format(holder.variable.name, period, array, array - remaining_array).encode('utf-8'))
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

setup(
name = 'OpenFisca-Core',
version = '23.1.4',
version = '23.1.5',
author = 'OpenFisca Team',
author_email = 'contact@openfisca.fr',
classifiers = [
Expand Down
9 changes: 9 additions & 0 deletions tests/core/test_holders.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,3 +168,12 @@ def test_cache_enum_on_disk():
simulation.calculate('housing_occupancy_status', month) # First calculation
housing_occupancy_status = simulation.calculate('housing_occupancy_status', month) # Read from cache
assert_equal(housing_occupancy_status, HousingOccupancyStatus.tenant)


def test_set_not_chaged_variable():
dont_cache_variable = MemoryConfig(max_memory_occupation = 1, variables_to_drop = ['salary'])
simulation = get_simulation(single, memory_config = dont_cache_variable)
holder = simulation.person.get_holder('salary')
array = np.asarray([2000])
holder.set_input('2015-01', array)
assert_equal(simulation.calculate('salary', '2015-01'), array)

0 comments on commit 8fff6dc

Please sign in to comment.