Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to set uncached variables when using a memory_config #687

Merged
merged 3 commits into from
Jul 11, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)