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

Add date units to periods #1139

Closed
wants to merge 71 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
ea6a7be
Add periods to doctests path
bonjourmauko Jul 28, 2022
39a296a
Add periods to tests path
bonjourmauko Jul 28, 2022
8e2b5fa
Ignore mypy periods' tests errors
bonjourmauko Jul 28, 2022
75f7f48
Fix instants' docstrings
bonjourmauko Jul 28, 2022
9b6f5f3
Fix periods' doctests
bonjourmauko Jul 28, 2022
b41bb5c
Fix periods' helpers doctests
bonjourmauko Jul 28, 2022
7a392f0
Add tests to periods.instant
bonjourmauko Jul 30, 2022
dcabc2b
Add tests to periods.instant_date
bonjourmauko Jul 30, 2022
dd875ad
Add tests to periods.key_period_size
bonjourmauko Jul 30, 2022
cd470f2
Add doctest to periods.unit_weights
bonjourmauko Jul 30, 2022
faee825
Add doctest to periods.unit_weight
bonjourmauko Jul 30, 2022
9969c9e
Fix typo in doc
bonjourmauko Jul 30, 2022
9832982
Extract raise error from period builder
bonjourmauko Jul 30, 2022
b33bf2d
Extract parse simple period from builder
bonjourmauko Jul 30, 2022
ef06ceb
Add tests to periods.period
bonjourmauko Jul 30, 2022
fc93df4
Refactor period's str year tests
bonjourmauko Jul 30, 2022
51cff30
Refactor period's str month tests
bonjourmauko Jul 30, 2022
5c3a163
Refactor period's str day tests
bonjourmauko Jul 30, 2022
2304eb4
Remove redundant examples
bonjourmauko Jul 30, 2022
521068f
Redistribute tests
bonjourmauko Jul 30, 2022
c7622ff
Consolidate tests
bonjourmauko Jul 30, 2022
af0f132
Version & CHANGELOG bump
bonjourmauko Jul 28, 2022
ad22d9e
Add date units to periods
bonjourmauko Jul 29, 2022
4fbb04c
Version & CHANGELOG bump
bonjourmauko Jul 29, 2022
9872a39
Fix flake8/pycodestyle dependency error
bonjourmauko Jul 31, 2022
35e02c5
Add periods to doctests path
bonjourmauko Jul 28, 2022
8ba7fe1
Ignore mypy periods' tests errors
bonjourmauko Jul 28, 2022
496951f
Fix instants' docstrings
bonjourmauko Jul 28, 2022
fbafc60
Fix periods' doctests
bonjourmauko Jul 28, 2022
1b8cfec
Fix periods' helpers doctests
bonjourmauko Jul 28, 2022
09fab88
Add tests to periods.instant
bonjourmauko Jul 30, 2022
2ecbdb8
Add tests to periods.instant_date
bonjourmauko Jul 30, 2022
0e51ac5
Add tests to periods.key_period_size
bonjourmauko Jul 30, 2022
a7e9851
Add doctest to periods.unit_weight
bonjourmauko Jul 30, 2022
aff6d23
Extract parse simple period from builder
bonjourmauko Jul 30, 2022
039468d
Add tests to periods.period
bonjourmauko Jul 30, 2022
85717fa
Refactor period's str year tests
bonjourmauko Jul 30, 2022
3fc64b6
Refactor period's str month tests
bonjourmauko Jul 30, 2022
7503d27
Refactor period's str day tests
bonjourmauko Jul 30, 2022
fed7c4a
Remove redundant examples
bonjourmauko Jul 30, 2022
bcd1edc
Redistribute tests
bonjourmauko Jul 30, 2022
309d58e
Consolidate tests
bonjourmauko Jul 30, 2022
fb6c119
Revert "Fix flake8/pycodestyle dependency error"
bonjourmauko Aug 1, 2022
5256174
Rationalise Instant doc & tests
bonjourmauko Aug 2, 2022
632566a
Simplify periods' doc
bonjourmauko Aug 2, 2022
45b1eb2
Rationalise period's offset tests
bonjourmauko Aug 2, 2022
01c1cd0
Version & CHANGELOG bump
bonjourmauko Jul 28, 2022
c5b2b1f
Reorder package
bonjourmauko Dec 14, 2022
f2e8085
Fix style
bonjourmauko Dec 14, 2022
35b03db
Rename zinstant` to `build_instant`
bonjourmauko Dec 14, 2022
746d29c
Rename to
bonjourmauko Dec 14, 2022
03ce49b
Move to
bonjourmauko Dec 14, 2022
4afec7a
Do not expose Instant cache
bonjourmauko Dec 14, 2022
4a3b32d
Fix documentation
bonjourmauko Dec 14, 2022
3c667e3
Fix circular dependencies
bonjourmauko Dec 14, 2022
6eb90a2
Make stricter
bonjourmauko Dec 14, 2022
31c2d32
Refactor _parse_unit
bonjourmauko Dec 14, 2022
9a96aed
Refactor as
bonjourmauko Dec 14, 2022
1b79d3c
Fix typing
bonjourmauko Dec 14, 2022
15a8678
Fix typing in py3.7
bonjourmauko Dec 14, 2022
c56c2a2
Rename period & instant
bonjourmauko Dec 14, 2022
51e2312
Fix imports
bonjourmauko Dec 14, 2022
baad937
Encapsulate periods
bonjourmauko Dec 14, 2022
7a11ece
Simplify dict
bonjourmauko Dec 14, 2022
69126fa
Remove assertion in periods.helpers
bonjourmauko Dec 14, 2022
996d987
Avoid inf to respect period type
bonjourmauko Dec 14, 2022
f34b6a6
Refactor offset
bonjourmauko Dec 14, 2022
923c8a0
Deprecate instant to date
bonjourmauko Dec 14, 2022
66224e5
Rename to
bonjourmauko Dec 14, 2022
3b3c27a
Fix typing
bonjourmauko Dec 15, 2022
2203fae
Update changes upstream
bonjourmauko Dec 15, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 4 additions & 3 deletions .github/get-numpy-version.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@

from __future__ import annotations

import os
import sys
import typing
from packaging import version
from typing import NoReturn, Union

import os
import sys

import numpy
from packaging import version

if typing.TYPE_CHECKING:
from packaging.version import LegacyVersion, Version
Expand Down
37 changes: 37 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,42 @@
# Changelog

## 39.1.0 [#1139](https://github.com/openfisca/openfisca-core/pull/1139)

#### New features

- Introduce `DateUnit` to `periods`
- Allows for transparent encapsulation of the atomic units of `periods` (`year`, `month`, ...).
- This helps with testing, refactoring and exrtension of `periods` (`weeks` for example).


# 39.0.0 [#1138](https://github.com/openfisca/openfisca-core/pull/1138)

#### Breaking changes

- Deprecate `instant_date`.
- Deprecate `periods.intersect`.
- Deprecate `periods.unit_weight`.
- Deprecate `periods.unit_weights`.
- Make `periods.parse_period` stricter (for example `2022-1` now fails).
- Refactor `Period.contains` as `Period.__contains__`.
- Rename `Period.get_subperiods` to `subperiods`.
- Rename `instant` to `build_instant`.
- Rename `period` to `build_period`.
- Transform `Instant.date` from property to method.
- Transform `Period.date` from property to method.

#### Technical changes

- Add typing to `openfisca_core.periods`.
- Document `openfisca_core.periods`.
- Fix `openfisca_core.periods` doctests.

#### Bug fixes

- Fixes impossible `last-of` and `first-of` offsets.
- Fixes incoherent dates,
- Fixes several race conditions,

# 38.0.0 [#989](https://github.com/openfisca/openfisca-core/pull/989)

#### New Features
Expand Down
3 changes: 1 addition & 2 deletions openfisca_core/commons/formulas.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
from openfisca_core.types import Array, ArrayLike
from typing import Any, Dict, Sequence, TypeVar

import numpy

from openfisca_core.types import ArrayLike, Array

T = TypeVar("T")


Expand Down
3 changes: 1 addition & 2 deletions openfisca_core/commons/misc.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from typing import TypeVar

from openfisca_core.types import Array
from typing import TypeVar

T = TypeVar("T")

Expand Down
3 changes: 1 addition & 2 deletions openfisca_core/commons/rates.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
from openfisca_core.types import Array, ArrayLike
from typing import Optional

import numpy

from openfisca_core.types import ArrayLike, Array


def average_rate(
target: Array[float],
Expand Down
14 changes: 7 additions & 7 deletions openfisca_core/data_storage/in_memory_storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ def __init__(self, is_eternal = False):

def get(self, period):
if self.is_eternal:
period = periods.period(periods.ETERNITY)
period = periods.period(period)
period = periods.build_period(periods.DateUnit.ETERNITY)
period = periods.build_period(period)

values = self._arrays.get(period)
if values is None:
Expand All @@ -24,8 +24,8 @@ def get(self, period):

def put(self, value, period):
if self.is_eternal:
period = periods.period(periods.ETERNITY)
period = periods.period(period)
period = periods.build_period(periods.DateUnit.ETERNITY)
period = periods.build_period(period)

self._arrays[period] = value

Expand All @@ -35,13 +35,13 @@ def delete(self, period = None):
return

if self.is_eternal:
period = periods.period(periods.ETERNITY)
period = periods.period(period)
period = periods.build_period(periods.DateUnit.ETERNITY)
period = periods.build_period(period)

self._arrays = {
period_item: value
for period_item, value in self._arrays.items()
if not period.contains(period_item)
if period_item not in period
}

def get_known_periods(self):
Expand Down
17 changes: 9 additions & 8 deletions openfisca_core/data_storage/on_disk_storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from openfisca_core import periods
from openfisca_core.indexed_enums import EnumArray
from openfisca_core.periods import DateUnit


class OnDiskStorage:
Expand All @@ -28,8 +29,8 @@ def _decode_file(self, file):

def get(self, period):
if self.is_eternal:
period = periods.period(periods.ETERNITY)
period = periods.period(period)
period = periods.build_period(DateUnit.ETERNITY)
period = periods.build_period(period)

values = self._files.get(period)
if values is None:
Expand All @@ -38,8 +39,8 @@ def get(self, period):

def put(self, value, period):
if self.is_eternal:
period = periods.period(periods.ETERNITY)
period = periods.period(period)
period = periods.build_period(DateUnit.ETERNITY)
period = periods.build_period(period)

filename = str(period)
path = os.path.join(self.storage_dir, filename) + '.npy'
Expand All @@ -55,14 +56,14 @@ def delete(self, period = None):
return

if self.is_eternal:
period = periods.period(periods.ETERNITY)
period = periods.period(period)
period = periods.build_period(DateUnit.ETERNITY)
period = periods.build_period(period)

if period is not None:
self._files = {
period_item: value
for period_item, value in self._files.items()
if not period.contains(period_item)
if period_item not in period
}

def get_known_periods(self):
Expand All @@ -76,7 +77,7 @@ def restore(self):
continue
path = os.path.join(self.storage_dir, filename)
filename_core = filename.rsplit('.', 1)[0]
period = periods.period(filename_core)
period = periods.build_period(filename_core)
files[period] = path

def __del__(self):
Expand Down
2 changes: 1 addition & 1 deletion openfisca_core/entities/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#
# See: https://www.python.org/dev/peps/pep-0008/#imports

from .helpers import build_entity # noqa: F401
from .role import Role # noqa: F401
from .entity import Entity # noqa: F401
from .group_entity import GroupEntity # noqa: F401
from .helpers import build_entity # noqa: F401
2 changes: 1 addition & 1 deletion openfisca_core/entities/entity.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from openfisca_core.types import TaxBenefitSystem, Variable
from typing import Any, Optional

import os
import textwrap

from openfisca_core.types import TaxBenefitSystem, Variable
from openfisca_core.entities import Role


Expand Down
9 changes: 6 additions & 3 deletions openfisca_core/errors/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,13 @@
from .cycle_error import CycleError # noqa: F401
from .empty_argument_error import EmptyArgumentError # noqa: F401
from .nan_creation_error import NaNCreationError # noqa: F401
from .parameter_not_found_error import ParameterNotFoundError, ParameterNotFoundError as ParameterNotFound # noqa: F401
from .parameter_not_found_error import ParameterNotFoundError # noqa: F401
from .parameter_not_found_error import ParameterNotFoundError as ParameterNotFound
from .parameter_parsing_error import ParameterParsingError # noqa: F401
from .period_mismatch_error import PeriodMismatchError # noqa: F401
from .situation_parsing_error import SituationParsingError # noqa: F401
from .spiral_error import SpiralError # noqa: F401
from .variable_name_config_error import VariableNameConflictError, VariableNameConflictError as VariableNameConflict # noqa: F401
from .variable_not_found_error import VariableNotFoundError, VariableNotFoundError as VariableNotFound # noqa: F401
from .variable_name_config_error import VariableNameConflictError # noqa: F401
from .variable_name_config_error import VariableNameConflictError as VariableNameConflict
from .variable_not_found_error import VariableNotFoundError # noqa: F401
from .variable_not_found_error import VariableNotFoundError as VariableNotFound
3 changes: 2 additions & 1 deletion openfisca_core/errors/empty_argument_error.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import typing

import os
import traceback
import typing

import numpy

Expand Down
6 changes: 5 additions & 1 deletion openfisca_core/formula_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,8 @@
# The following are transitional imports to ensure non-breaking changes.
# Could be deprecated in the next major release.

from openfisca_core.commons import apply_thresholds, concat, switch # noqa: F401
from openfisca_core.commons import ( # noqa: F401
apply_thresholds,
concat,
switch,
)
5 changes: 4 additions & 1 deletion openfisca_core/holders/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
#
# See: https://www.python.org/dev/peps/pep-0008/#imports

from .helpers import set_input_dispatch_by_period, set_input_divide_by_period # noqa: F401
from .helpers import ( # noqa: F401
set_input_dispatch_by_period,
set_input_divide_by_period,
)
from .holder import Holder # noqa: F401
from .memory_usage import MemoryUsage # noqa: F401
4 changes: 2 additions & 2 deletions openfisca_core/holders/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def set_input_dispatch_by_period(holder, period, array):
period_size = period.size
period_unit = period.unit

if holder.variable.definition_period == periods.ETERNITY:
if holder.variable.definition_period == periods.DateUnit.ETERNITY:
raise ValueError("set_input_dispatch_by_period can't be used for eternal variables.")

cached_period_unit = holder.variable.definition_period
Expand Down Expand Up @@ -53,7 +53,7 @@ def set_input_divide_by_period(holder, period, array):
period_size = period.size
period_unit = period.unit

if holder.variable.definition_period == periods.ETERNITY:
if holder.variable.definition_period == periods.DateUnit.ETERNITY:
raise ValueError("set_input_divide_by_period can't be used for eternal variables.")

cached_period_unit = holder.variable.definition_period
Expand Down
35 changes: 18 additions & 17 deletions openfisca_core/holders/holder.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations

from openfisca_core.periods.typing import Period
from typing import Any, Optional, Sequence, Union

import os
Expand All @@ -8,15 +9,11 @@
import numpy
import psutil

from openfisca_core import (
errors,
commons,
data_storage as storage,
indexed_enums as enums,
periods,
tools,
types,
)
from openfisca_core import commons
from openfisca_core import data_storage as storage
from openfisca_core import errors
from openfisca_core import indexed_enums as enums
from openfisca_core import periods, tools

from .memory_usage import MemoryUsage

Expand All @@ -30,7 +27,7 @@ def __init__(self, variable, population):
self.population = population
self.variable = variable
self.simulation = population.simulation
self._memory_storage = storage.InMemoryStorage(is_eternal = (self.variable.definition_period == periods.ETERNITY))
self._memory_storage = storage.InMemoryStorage(is_eternal = (self.variable.definition_period == periods.DateUnit.ETERNITY))

# By default, do not activate on-disk storage, or variable dropping
self._disk_storage = None
Expand Down Expand Up @@ -67,7 +64,7 @@ def create_disk_storage(self, directory = None, preserve = False):
os.mkdir(storage_dir)
return storage.OnDiskStorage(
storage_dir,
is_eternal = (self.variable.definition_period == periods.ETERNITY),
is_eternal = (self.variable.definition_period == periods.DateUnit.ETERNITY),
preserve_storage_dir = preserve
)

Expand Down Expand Up @@ -164,7 +161,7 @@ def get_known_periods(self):

def set_input(
self,
period: types.Period,
period: Period,
array: Union[numpy.ndarray, Sequence[Any]],
) -> Optional[numpy.ndarray]:
"""Set a Variable's array of values of a given Period.
Expand Down Expand Up @@ -210,10 +207,14 @@ def set_input(

"""

period = periods.period(period)
if period.unit == periods.ETERNITY and self.variable.definition_period != periods.ETERNITY:
period = periods.build_period(period)

if period is None:
raise ValueError(f"Invalid period value: {period}")

if period.unit == periods.DateUnit.ETERNITY and self.variable.definition_period != periods.DateUnit.ETERNITY:
error_message = os.linesep.join([
'Unable to set a value for variable {0} for periods.ETERNITY.',
'Unable to set a value for variable {0} for DateUnit.ETERNITY.',
'{0} is only defined for {1}s. Please adapt your input.',
]).format(
self.variable.name,
Expand Down Expand Up @@ -260,9 +261,9 @@ def _to_array(self, value):

def _set(self, period, value):
value = self._to_array(value)
if self.variable.definition_period != periods.ETERNITY:
if self.variable.definition_period != periods.DateUnit.ETERNITY:
if period is None:
raise ValueError('A period must be specified to set values, except for variables with periods.ETERNITY as as period_definition.')
raise ValueError('A period must be specified to set values, except for variables with DateUnit.ETERNITY as as period_definition.')
if (self.variable.definition_period != period.unit or period.size > 1):
name = self.variable.name
period_size_adj = f'{period.unit}' if (period.size == 1) else f'{period.size}-{period.unit}s'
Expand Down