diff --git a/openfisca_core/data_storage/in_memory_storage.py b/openfisca_core/data_storage/in_memory_storage.py index bd40460a56..a82977c9d0 100644 --- a/openfisca_core/data_storage/in_memory_storage.py +++ b/openfisca_core/data_storage/in_memory_storage.py @@ -1,6 +1,7 @@ import numpy from openfisca_core import periods +from openfisca_core.periods import DateUnit class InMemoryStorage: @@ -14,7 +15,7 @@ def __init__(self, is_eternal = False): def get(self, period): if self.is_eternal: - period = periods.period(periods.ETERNITY) + period = periods.period(DateUnit.ETERNITY) period = periods.period(period) values = self._arrays.get(period) @@ -24,7 +25,7 @@ def get(self, period): def put(self, value, period): if self.is_eternal: - period = periods.period(periods.ETERNITY) + period = periods.period(DateUnit.ETERNITY) period = periods.period(period) self._arrays[period] = value @@ -35,7 +36,7 @@ def delete(self, period = None): return if self.is_eternal: - period = periods.period(periods.ETERNITY) + period = periods.period(DateUnit.ETERNITY) period = periods.period(period) self._arrays = { diff --git a/openfisca_core/data_storage/on_disk_storage.py b/openfisca_core/data_storage/on_disk_storage.py index 10d4696b58..97bb582785 100644 --- a/openfisca_core/data_storage/on_disk_storage.py +++ b/openfisca_core/data_storage/on_disk_storage.py @@ -4,6 +4,7 @@ import numpy from openfisca_core import periods +from openfisca_core.periods import DateUnit from openfisca_core.indexed_enums import EnumArray @@ -28,7 +29,7 @@ def _decode_file(self, file): def get(self, period): if self.is_eternal: - period = periods.period(periods.ETERNITY) + period = periods.period(DateUnit.ETERNITY) period = periods.period(period) values = self._files.get(period) @@ -38,7 +39,7 @@ def get(self, period): def put(self, value, period): if self.is_eternal: - period = periods.period(periods.ETERNITY) + period = periods.period(DateUnit.ETERNITY) period = periods.period(period) filename = str(period) @@ -55,7 +56,7 @@ def delete(self, period = None): return if self.is_eternal: - period = periods.period(periods.ETERNITY) + period = periods.period(DateUnit.ETERNITY) period = periods.period(period) if period is not None: diff --git a/openfisca_core/holders/helpers.py b/openfisca_core/holders/helpers.py index efe16388e0..96c6d964fa 100644 --- a/openfisca_core/holders/helpers.py +++ b/openfisca_core/holders/helpers.py @@ -2,7 +2,7 @@ import numpy -from openfisca_core import periods +from openfisca_core.periods import DateUnit log = logging.getLogger(__name__) @@ -20,10 +20,10 @@ def set_input_dispatch_by_period(holder, period, array): period_size = period.size period_unit = period.unit - if holder.variable.definition_period == periods.MONTH: - cached_period_unit = periods.MONTH - elif holder.variable.definition_period == periods.YEAR: - cached_period_unit = periods.YEAR + if holder.variable.definition_period == DateUnit.MONTH: + cached_period_unit = DateUnit.MONTH + elif holder.variable.definition_period == DateUnit.YEAR: + cached_period_unit = DateUnit.YEAR else: raise ValueError('set_input_dispatch_by_period can be used only for yearly or monthly variables.') @@ -55,10 +55,10 @@ def set_input_divide_by_period(holder, period, array): period_size = period.size period_unit = period.unit - if holder.variable.definition_period == periods.MONTH: - cached_period_unit = periods.MONTH - elif holder.variable.definition_period == periods.YEAR: - cached_period_unit = periods.YEAR + if holder.variable.definition_period == DateUnit.MONTH: + cached_period_unit = DateUnit.MONTH + elif holder.variable.definition_period == DateUnit.YEAR: + cached_period_unit = DateUnit.YEAR else: raise ValueError('set_input_divide_by_period can be used only for yearly or monthly variables.') diff --git a/openfisca_core/holders/holder.py b/openfisca_core/holders/holder.py index 3d0379d22d..355d50f9d5 100644 --- a/openfisca_core/holders/holder.py +++ b/openfisca_core/holders/holder.py @@ -8,6 +8,7 @@ from openfisca_core.errors import PeriodMismatchError from openfisca_core.data_storage import InMemoryStorage, OnDiskStorage from openfisca_core.indexed_enums import Enum +from openfisca_core.periods import DateUnit class Holder: @@ -19,7 +20,7 @@ def __init__(self, variable, population): self.population = population self.variable = variable self.simulation = population.simulation - self._memory_storage = InMemoryStorage(is_eternal = (self.variable.definition_period == periods.ETERNITY)) + self._memory_storage = InMemoryStorage(is_eternal = (self.variable.definition_period == DateUnit.ETERNITY)) # By default, do not activate on-disk storage, or variable dropping self._disk_storage = None @@ -56,7 +57,7 @@ def create_disk_storage(self, directory = None, preserve = False): os.mkdir(storage_dir) return OnDiskStorage( storage_dir, - is_eternal = (self.variable.definition_period == periods.ETERNITY), + is_eternal = (self.variable.definition_period == DateUnit.ETERNITY), preserve_storage_dir = preserve ) @@ -148,9 +149,9 @@ def set_input(self, period, array): """ period = periods.period(period) - if period.unit == periods.ETERNITY and self.variable.definition_period != periods.ETERNITY: + if period.unit == DateUnit.ETERNITY and self.variable.definition_period != 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, @@ -197,9 +198,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 != 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' diff --git a/openfisca_core/periods/__init__.py b/openfisca_core/periods/__init__.py index 4cd9db648c..dd35548818 100644 --- a/openfisca_core/periods/__init__.py +++ b/openfisca_core/periods/__init__.py @@ -42,5 +42,6 @@ unit_weight, ) +from .date_unit import DateUnit # noqa: F401 from .instant_ import Instant # noqa: F401 from .period_ import Period # noqa: F401 diff --git a/openfisca_core/periods/config.py b/openfisca_core/periods/config.py index 6e0c698098..f81a55c122 100644 --- a/openfisca_core/periods/config.py +++ b/openfisca_core/periods/config.py @@ -1,15 +1,17 @@ import re -import typing +from typing import Dict -DAY = 'day' -MONTH = 'month' -YEAR = 'year' -ETERNITY = 'eternity' +from .date_unit import DateUnit + +DAY = DateUnit.DAY +MONTH = DateUnit.MONTH +YEAR = DateUnit.YEAR +ETERNITY = DateUnit.ETERNITY # Matches "2015", "2015-01", "2015-01-01" # Does not match "2015-13", "2015-12-32" INSTANT_PATTERN = re.compile(r"^\d{4}(-(0[1-9]|1[012]))?(-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01]))?$") -date_by_instant_cache: typing.Dict = {} -str_by_instant_cache: typing.Dict = {} +date_by_instant_cache: Dict = {} +str_by_instant_cache: Dict = {} year_or_month_or_day_re = re.compile(r'(18|19|20)\d{2}(-(0?[1-9]|1[0-2])(-([0-2]?\d|3[0-1]))?)?$') diff --git a/openfisca_core/periods/date_unit.py b/openfisca_core/periods/date_unit.py new file mode 100644 index 0000000000..8faac750ab --- /dev/null +++ b/openfisca_core/periods/date_unit.py @@ -0,0 +1,54 @@ +from strenum import StrEnum + + +class DateUnit(StrEnum): + """The date units of a rule system. + + Examples: + >>> repr(DateUnit) + "" + + >>> repr(DateUnit.DAY) + "" + + >>> str(DateUnit.DAY) + 'day' + + >>> dict([(DateUnit.DAY, DateUnit.DAY.value)]) + {: 'day'} + + >>> list(DateUnit) + [, , ...] + + >>> len(DateUnit) + 4 + + >>> DateUnit["DAY"] + + + >>> DateUnit(DateUnit.DAY) + + + >>> DateUnit.DAY in DateUnit + True + + >>> "day" in list(DateUnit) + True + + >>> DateUnit.DAY == "day" + True + + >>> DateUnit.DAY.name + 'DAY' + + >>> DateUnit.DAY.value + 'day' + + .. versionadded:: 35.9.0 + + """ + + DAY = "day" + MONTH = "month" + YEAR = "year" + ETERNITY = "eternity" diff --git a/openfisca_core/periods/helpers.py b/openfisca_core/periods/helpers.py index 2002774aa1..5c016e3879 100644 --- a/openfisca_core/periods/helpers.py +++ b/openfisca_core/periods/helpers.py @@ -3,6 +3,7 @@ from typing import Dict, NoReturn, Optional from . import config +from .date_unit import DateUnit from .instant_ import Instant from .period_ import Period @@ -37,7 +38,7 @@ def instant(instant) -> Optional[Instant]: >>> instant(Instant((2021, 9, 16))) Instant((2021, 9, 16)) - >>> instant(Period(("year", Instant((2021, 9, 16)), 1))) + >>> instant(Period((DateUnit.YEAR, Instant((2021, 9, 16)), 1))) Instant((2021, 9, 16)) >>> instant(2021) @@ -115,35 +116,35 @@ def period(value) -> Period: :exc:`ValueError`: When the arguments were invalid, like "2021-32-13". Examples: - >>> period(Period(("year", Instant((2021, 1, 1)), 1))) - Period(('year', Instant((2021, 1, 1)), 1)) + >>> period(Period((DateUnit.YEAR, Instant((2021, 1, 1)), 1))) + Period((, Instant((2021, 1, 1)), 1)) >>> period(Instant((2021, 1, 1))) - Period(('day', Instant((2021, 1, 1)), 1)) + Period((, Instant((2021, 1, 1)), 1)) - >>> period("eternity") - Period(('eternity', Instant((1, 1, 1)), inf)) + >>> period(DateUnit.ETERNITY) + Period((, Instant((1, 1, 1)), inf)) >>> period(2021) - Period(('year', Instant((2021, 1, 1)), 1)) + Period((, Instant((2021, 1, 1)), 1)) >>> period("2014") - Period(('year', Instant((2014, 1, 1)), 1)) + Period((, Instant((2014, 1, 1)), 1)) >>> period("year:2014") - Period(('year', Instant((2014, 1, 1)), 1)) + Period((, Instant((2014, 1, 1)), 1)) >>> period("month:2014-2") - Period(('month', Instant((2014, 2, 1)), 1)) + Period((, Instant((2014, 2, 1)), 1)) >>> period("year:2014-2") - Period(('year', Instant((2014, 2, 1)), 1)) + Period((, Instant((2014, 2, 1)), 1)) >>> period("day:2014-2-2") - Period(('day', Instant((2014, 2, 2)), 1)) + Period((, Instant((2014, 2, 2)), 1)) >>> period("day:2014-2-2:3") - Period(('day', Instant((2014, 2, 2)), 3)) + Period((, Instant((2014, 2, 2)), 3)) """ @@ -151,14 +152,14 @@ def period(value) -> Period: return value if isinstance(value, Instant): - return Period((config.DAY, value, 1)) + return Period((DateUnit.DAY, value, 1)) - if value == 'ETERNITY' or value == config.ETERNITY: - return Period(('eternity', instant(datetime.date.min), float("inf"))) + if value == 'ETERNITY' or value == DateUnit.ETERNITY: + return Period((DateUnit.ETERNITY, instant(datetime.date.min), float("inf"))) # check the type if isinstance(value, int): - return Period((config.YEAR, Instant((value, 1, 1)), 1)) + return Period((DateUnit.YEAR, Instant((value, 1, 1)), 1)) if not isinstance(value, str): _raise_error(value) @@ -175,9 +176,13 @@ def period(value) -> Period: # left-most component must be a valid unit unit = components[0] - if unit not in (config.DAY, config.MONTH, config.YEAR): + + if unit not in (DateUnit.DAY, DateUnit.MONTH, DateUnit.YEAR): _raise_error(value) + else: + unit = DateUnit(unit) + # middle component must be a valid iso period base_period = _parse_simple_period(components[1]) if not base_period: @@ -210,13 +215,13 @@ def _parse_simple_period(value: str) -> Optional[Period]: Examples: >>> _parse_simple_period("2022") - Period(('year', Instant((2022, 1, 1)), 1)) + Period((, Instant((2022, 1, 1)), 1)) >>> _parse_simple_period("2022-02") - Period(('month', Instant((2022, 2, 1)), 1)) + Period((, Instant((2022, 2, 1)), 1)) >>> _parse_simple_period("2022-02-13") - Period(('day', Instant((2022, 2, 13)), 1)) + Period((, Instant((2022, 2, 13)), 1)) """ @@ -231,11 +236,11 @@ def _parse_simple_period(value: str) -> Optional[Period]: except ValueError: return None else: - return Period((config.DAY, Instant((date.year, date.month, date.day)), 1)) + return Period((DateUnit.DAY, Instant((date.year, date.month, date.day)), 1)) else: - return Period((config.MONTH, Instant((date.year, date.month, 1)), 1)) + return Period((DateUnit.MONTH, Instant((date.year, date.month, 1)), 1)) else: - return Period((config.YEAR, Instant((date.year, date.month, 1)), 1)) + return Period((DateUnit.YEAR, Instant((date.year, date.month, 1)), 1)) def _raise_error(value: str) -> NoReturn: @@ -244,7 +249,7 @@ def _raise_error(value: str) -> NoReturn: Examples: >>> _raise_error("Oi mate!") Traceback (most recent call last): - ValueError: Expected a period (eg. '2017', '2017-01', '2017-01-01', ...); got: 'Oi mate!'. + ValueError: Expected a period (eg. '2017', ...); got: 'Oi mate!'. """ @@ -270,11 +275,11 @@ def key_period_size(period: Period) -> str: Examples: >>> instant = Instant((2021, 9, 14)) - >>> period = Period(("day", instant, 1)) + >>> period = Period((DateUnit.DAY, instant, 1)) >>> key_period_size(period) '100_1' - >>> period = Period(("year", instant, 3)) + >>> period = Period((DateUnit.YEAR, instant, 3)) >>> key_period_size(period) '300_3' @@ -290,15 +295,15 @@ def unit_weights() -> Dict[str, int]: Examples: >>> unit_weights() - {'day': 100, ...} + {: 100, ...: 400} """ return { - config.DAY: 100, - config.MONTH: 200, - config.YEAR: 300, - config.ETERNITY: 400, + DateUnit.DAY: 100, + DateUnit.MONTH: 200, + DateUnit.YEAR: 300, + DateUnit.ETERNITY: 400, } @@ -306,7 +311,7 @@ def unit_weight(unit: str) -> int: """Retrieves a specific date unit weight. Examples: - >>> unit_weight("day") + >>> unit_weight(DateUnit.DAY) 100 """ diff --git a/openfisca_core/periods/instant_.py b/openfisca_core/periods/instant_.py index a9a5e32779..a5cf9e2591 100644 --- a/openfisca_core/periods/instant_.py +++ b/openfisca_core/periods/instant_.py @@ -3,13 +3,14 @@ from .. import periods from . import config +from .date_unit import DateUnit class Instant(tuple): """An instant in time (year, month, day). An :class:`.Instant` represents the most atomic and indivisible - legislation's time unit. + legislation's date unit. Current implementation considers this unit to be a day, so :obj:`instants <.Instant>` can be thought of as "day dates". @@ -118,15 +119,15 @@ def period(self, unit, size = 1): :exc:`AssertionError`: When ``size`` is not an unsigned :obj:`int`. Examples: - >>> Instant((2021, 9, 13)).period("year") - Period(('year', Instant((2021, 9, 13)), 1)) + >>> Instant((2021, 9, 13)).period(DateUnit.YEAR) + Period((, Instant((2021, 9, 13)), 1)) - >>> Instant((2021, 9, 13)).period("month", 2) - Period(('month', Instant((2021, 9, 13)), 2)) + >>> Instant((2021, 9, 13)).period(DateUnit.MONTH, 2) + Period((, Instant((2021, 9, 13)), 2)) """ - assert unit in (config.DAY, config.MONTH, config.YEAR), 'Invalid unit: {} of type {}'.format(unit, type(unit)) + assert unit in (DateUnit.DAY, DateUnit.MONTH, DateUnit.YEAR), 'Invalid unit: {} of type {}'.format(unit, type(unit)) assert isinstance(size, int) and size >= 1, 'Invalid size: {} of type {}'.format(size, type(size)) return periods.Period((unit, self, size)) @@ -146,37 +147,37 @@ def offset(self, offset, unit): ``last-of``, or any :obj:`int`. Examples: - >>> Instant((2020, 12, 31)).offset("first-of", "month") + >>> Instant((2020, 12, 31)).offset("first-of", DateUnit.MONTH) Instant((2020, 12, 1)) - >>> Instant((2020, 1, 1)).offset("last-of", "year") + >>> Instant((2020, 1, 1)).offset("last-of", DateUnit.YEAR) Instant((2020, 12, 31)) - >>> Instant((2020, 1, 1)).offset(1, "year") + >>> Instant((2020, 1, 1)).offset(1, DateUnit.YEAR) Instant((2021, 1, 1)) - >>> Instant((2020, 1, 1)).offset(-3, "day") + >>> Instant((2020, 1, 1)).offset(-3, DateUnit.DAY) Instant((2019, 12, 29)) """ year, month, day = self - assert unit in (config.DAY, config.MONTH, config.YEAR), 'Invalid unit: {} of type {}'.format(unit, type(unit)) + assert unit in (DateUnit.DAY, DateUnit.MONTH, DateUnit.YEAR), 'Invalid unit: {} of type {}'.format(unit, type(unit)) if offset == 'first-of': - if unit == config.MONTH: + if unit == DateUnit.MONTH: day = 1 - elif unit == config.YEAR: + elif unit == DateUnit.YEAR: month = 1 day = 1 elif offset == 'last-of': - if unit == config.MONTH: + if unit == DateUnit.MONTH: day = calendar.monthrange(year, month)[1] - elif unit == config.YEAR: + elif unit == DateUnit.YEAR: month = 12 day = 31 else: assert isinstance(offset, int), 'Invalid offset: {} of type {}'.format(offset, type(offset)) - if unit == config.DAY: + if unit == DateUnit.DAY: day += offset if offset < 0: while day < 1: @@ -194,7 +195,7 @@ def offset(self, offset, unit): month = 1 day -= month_last_day month_last_day = calendar.monthrange(year, month)[1] - elif unit == config.MONTH: + elif unit == DateUnit.MONTH: month += offset if offset < 0: while month < 1: @@ -207,7 +208,7 @@ def offset(self, offset, unit): month_last_day = calendar.monthrange(year, month)[1] if day > month_last_day: day = month_last_day - elif unit == config.YEAR: + elif unit == DateUnit.YEAR: year += offset # Handle february month of leap year. month_last_day = calendar.monthrange(year, month)[1] diff --git a/openfisca_core/periods/period_.py b/openfisca_core/periods/period_.py index d343e3df05..814860a026 100644 --- a/openfisca_core/periods/period_.py +++ b/openfisca_core/periods/period_.py @@ -2,7 +2,8 @@ import calendar -from . import config, helpers +from . import helpers +from .date_unit import DateUnit from .instant_ import Instant @@ -25,13 +26,13 @@ class Period(tuple): Examples: >>> instant = Instant((2021, 9, 1)) - >>> period = Period(("year", instant, 3)) + >>> period = Period((DateUnit.YEAR, instant, 3)) >>> repr(Period) "" >>> repr(period) - "Period(('year', Instant((2021, 9, 1)), 3))" + "Period((, Instant((2021, 9, 1)), 3))" >>> str(period) 'year:2021-09:3' @@ -41,10 +42,10 @@ class Period(tuple): ValueError: dictionary update sequence element #0 has length 3... >>> list(period) - ['year', Instant((2021, 9, 1)), 3] + [, Instant((2021, 9, 1)), 3] >>> period[0] - 'year' + >>> period[0] in period True @@ -52,29 +53,29 @@ class Period(tuple): >>> len(period) 3 - >>> period == Period(("year", instant, 3)) + >>> period == Period((DateUnit.YEAR, instant, 3)) True - >>> period != Period(("year", instant, 3)) + >>> period != Period((DateUnit.YEAR, instant, 3)) False - >>> period > Period(("year", instant, 3)) + >>> period > Period((DateUnit.YEAR, instant, 3)) False - >>> period < Period(("year", instant, 3)) + >>> period < Period((DateUnit.YEAR, instant, 3)) False - >>> period >= Period(("year", instant, 3)) + >>> period >= Period((DateUnit.YEAR, instant, 3)) True - >>> period <= Period(("year", instant, 3)) + >>> period <= Period((DateUnit.YEAR, instant, 3)) True >>> period.date Traceback (most recent call last): AssertionError: "date" is undefined for a period of size > 1 - >>> Period(("year", instant, 1)).date + >>> Period((DateUnit.YEAR, instant, 1)).date datetime.date(2021, 9, 1) >>> period.days @@ -96,28 +97,28 @@ class Period(tuple): Instant((2024, 8, 31)) >>> period.unit - 'year' + >>> period.last_3_months - Period(('month', Instant((2021, 6, 1)), 3)) + Period((, Instant((2021, 6, 1)), 3)) >>> period.last_month - Period(('month', Instant((2021, 8, 1)), 1)) + Period((, Instant((2021, 8, 1)), 1)) >>> period.last_year - Period(('year', Instant((2020, 1, 1)), 1)) + Period((, Instant((2020, 1, 1)), 1)) >>> period.n_2 - Period(('year', Instant((2019, 1, 1)), 1)) + Period((, Instant((2019, 1, 1)), 1)) >>> period.this_year - Period(('year', Instant((2021, 1, 1)), 1)) + Period((, Instant((2021, 1, 1)), 1)) >>> period.first_month - Period(('month', Instant((2021, 9, 1)), 1)) + Period((, Instant((2021, 9, 1)), 1)) >>> period.first_day - Period(('day', Instant((2021, 9, 1)), 1)) + Period((, Instant((2021, 9, 1)), 1)) """ @@ -126,26 +127,26 @@ def __repr__(self) -> str: def __str__(self) -> str: unit, start_instant, size = self - if unit == config.ETERNITY: + if unit == DateUnit.ETERNITY: return 'ETERNITY' year, month, day = start_instant # 1 year long period - if (unit == config.MONTH and size == 12 or unit == config.YEAR and size == 1): + if (unit == DateUnit.MONTH and size == 12 or unit == DateUnit.YEAR and size == 1): if month == 1: # civil year starting from january return str(year) else: # rolling year - return '{}:{}-{:02d}'.format(config.YEAR, year, month) + return '{}:{}-{:02d}'.format(DateUnit.YEAR, year, month) # simple month - if unit == config.MONTH and size == 1: + if unit == DateUnit.MONTH and size == 1: return '{}-{:02d}'.format(year, month) # several civil years - if unit == config.YEAR and month == 1: + if unit == DateUnit.YEAR and month == 1: return '{}:{}:{}'.format(unit, year, size) - if unit == config.DAY: + if unit == DateUnit.DAY: if size == 1: return '{}-{:02d}-{:02d}'.format(year, month, day) else: @@ -182,14 +183,14 @@ def intersection(self, start, stop): if intersection_start.day == 1 and intersection_start.month == 1 \ and intersection_stop.day == 31 and intersection_stop.month == 12: return self.__class__(( - 'year', + DateUnit.YEAR, intersection_start, intersection_stop.year - intersection_start.year + 1, )) if intersection_start.day == 1 and intersection_stop.day == calendar.monthrange(intersection_stop.year, intersection_stop.month)[1]: return self.__class__(( - 'month', + DateUnit.MONTH, intersection_start, ( (intersection_stop.year - intersection_start.year) * 12 @@ -199,7 +200,7 @@ def intersection(self, start, stop): ), )) return self.__class__(( - 'day', + DateUnit.DAY, intersection_start, (intersection_stop.date - intersection_start.date).days + 1, )) @@ -208,199 +209,199 @@ def get_subperiods(self, unit): """Return the list of periods of unit ``unit`` contained in self. Examples: - >>> period = Period(("year", Instant((2021, 1, 1)), 1)) - >>> period.get_subperiods("month") - [Period(('month', Instant((2021, 1, 1)), 1)),...2021, 12, 1)), 1))] + >>> period = Period((DateUnit.YEAR, Instant((2021, 1, 1)), 1)) + >>> period.get_subperiods(DateUnit.MONTH) + [Period((, Instant((2021, 1, 1)), 1)),...2021, 12, 1)), 1))] - >>> period = Period(("year", Instant((2021, 1, 1)), 2)) - >>> period.get_subperiods("year") - [Period(('year', Instant((2021, 1, 1)), 1)),...((2022, 1, 1)), 1))] + >>> period = Period((DateUnit.YEAR, Instant((2021, 1, 1)), 2)) + >>> period.get_subperiods(DateUnit.YEAR) + [Period((, Instant((2021, 1, 1)), 1)),...((2022, 1, 1)), 1))] """ if helpers.unit_weight(self.unit) < helpers.unit_weight(unit): raise ValueError('Cannot subdivide {0} into {1}'.format(self.unit, unit)) - if unit == config.YEAR: - return [self.this_year.offset(i, config.YEAR) for i in range(self.size)] + if unit == DateUnit.YEAR: + return [self.this_year.offset(i, DateUnit.YEAR) for i in range(self.size)] - if unit == config.MONTH: - return [self.first_month.offset(i, config.MONTH) for i in range(self.size_in_months)] + if unit == DateUnit.MONTH: + return [self.first_month.offset(i, DateUnit.MONTH) for i in range(self.size_in_months)] - if unit == config.DAY: - return [self.first_day.offset(i, config.DAY) for i in range(self.size_in_days)] + if unit == DateUnit.DAY: + return [self.first_day.offset(i, DateUnit.DAY) for i in range(self.size_in_days)] def offset(self, offset, unit = None): """Increment (or decrement) the given period with offset units. Examples: - >>> Period(("day", Instant((2021, 1, 1)), 365)).offset(1) - Period(('day', Instant((2021, 1, 2)), 365)) + >>> Period((DateUnit.DAY, Instant((2021, 1, 1)), 365)).offset(1) + Period((, Instant((2021, 1, 2)), 365)) - >>> Period(("day", Instant((2021, 1, 1)), 365)).offset(1, "day") - Period(('day', Instant((2021, 1, 2)), 365)) + >>> Period((DateUnit.DAY, Instant((2021, 1, 1)), 365)).offset(1, DateUnit.DAY) + Period((, Instant((2021, 1, 2)), 365)) - >>> Period(("day", Instant((2021, 1, 1)), 365)).offset(1, "month") - Period(('day', Instant((2021, 2, 1)), 365)) + >>> Period((DateUnit.DAY, Instant((2021, 1, 1)), 365)).offset(1, DateUnit.MONTH) + Period((, Instant((2021, 2, 1)), 365)) - >>> Period(("day", Instant((2021, 1, 1)), 365)).offset(1, "year") - Period(('day', Instant((2022, 1, 1)), 365)) + >>> Period((DateUnit.DAY, Instant((2021, 1, 1)), 365)).offset(1, DateUnit.YEAR) + Period((, Instant((2022, 1, 1)), 365)) - >>> Period(("month", Instant((2021, 1, 1)), 12)).offset(1) - Period(('month', Instant((2021, 2, 1)), 12)) + >>> Period((DateUnit.MONTH, Instant((2021, 1, 1)), 12)).offset(1) + Period((, Instant((2021, 2, 1)), 12)) - >>> Period(("month", Instant((2021, 1, 1)), 12)).offset(1, "day") - Period(('month', Instant((2021, 1, 2)), 12)) + >>> Period((DateUnit.MONTH, Instant((2021, 1, 1)), 12)).offset(1, DateUnit.DAY) + Period((, Instant((2021, 1, 2)), 12)) - >>> Period(("month", Instant((2021, 1, 1)), 12)).offset(1, "month") - Period(('month', Instant((2021, 2, 1)), 12)) + >>> Period((DateUnit.MONTH, Instant((2021, 1, 1)), 12)).offset(1, DateUnit.MONTH) + Period((, Instant((2021, 2, 1)), 12)) - >>> Period(("month", Instant((2021, 1, 1)), 12)).offset(1, "year") - Period(('month', Instant((2022, 1, 1)), 12)) + >>> Period((DateUnit.MONTH, Instant((2021, 1, 1)), 12)).offset(1, DateUnit.YEAR) + Period((, Instant((2022, 1, 1)), 12)) - >>> Period(("year", Instant((2021, 1, 1)), 1)).offset(1) - Period(('year', Instant((2022, 1, 1)), 1)) + >>> Period((DateUnit.YEAR, Instant((2021, 1, 1)), 1)).offset(1) + Period((, Instant((2022, 1, 1)), 1)) - >>> Period(("year", Instant((2021, 1, 1)), 1)).offset(1, "day") - Period(('year', Instant((2021, 1, 2)), 1)) + >>> Period((DateUnit.YEAR, Instant((2021, 1, 1)), 1)).offset(1, DateUnit.DAY) + Period((, Instant((2021, 1, 2)), 1)) - >>> Period(("year", Instant((2021, 1, 1)), 1)).offset(1, "month") - Period(('year', Instant((2021, 2, 1)), 1)) + >>> Period((DateUnit.YEAR, Instant((2021, 1, 1)), 1)).offset(1, DateUnit.MONTH) + Period((, Instant((2021, 2, 1)), 1)) - >>> Period(("year", Instant((2021, 1, 1)), 1)).offset(1, "year") - Period(('year', Instant((2022, 1, 1)), 1)) + >>> Period((DateUnit.YEAR, Instant((2021, 1, 1)), 1)).offset(1, DateUnit.YEAR) + Period((, Instant((2022, 1, 1)), 1)) - >>> Period(("day", Instant((2011, 2, 28)), 1)).offset(1) - Period(('day', Instant((2011, 3, 1)), 1)) + >>> Period((DateUnit.DAY, Instant((2011, 2, 28)), 1)).offset(1) + Period((, Instant((2011, 3, 1)), 1)) - >>> Period(("month", Instant((2011, 2, 28)), 1)).offset(1) - Period(('month', Instant((2011, 3, 28)), 1)) + >>> Period((DateUnit.MONTH, Instant((2011, 2, 28)), 1)).offset(1) + Period((, Instant((2011, 3, 28)), 1)) - >>> Period(("year", Instant((2011, 2, 28)), 1)).offset(1) - Period(('year', Instant((2012, 2, 28)), 1)) + >>> Period((DateUnit.YEAR, Instant((2011, 2, 28)), 1)).offset(1) + Period((, Instant((2012, 2, 28)), 1)) - >>> Period(("day", Instant((2011, 3, 1)), 1)).offset(-1) - Period(('day', Instant((2011, 2, 28)), 1)) + >>> Period((DateUnit.DAY, Instant((2011, 3, 1)), 1)).offset(-1) + Period((, Instant((2011, 2, 28)), 1)) - >>> Period(("month", Instant((2011, 3, 1)), 1)).offset(-1) - Period(('month', Instant((2011, 2, 1)), 1)) + >>> Period((DateUnit.MONTH, Instant((2011, 3, 1)), 1)).offset(-1) + Period((, Instant((2011, 2, 1)), 1)) - >>> Period(("year", Instant((2011, 3, 1)), 1)).offset(-1) - Period(('year', Instant((2010, 3, 1)), 1)) + >>> Period((DateUnit.YEAR, Instant((2011, 3, 1)), 1)).offset(-1) + Period((, Instant((2010, 3, 1)), 1)) - >>> Period(("day", Instant((2014, 1, 30)), 1)).offset(3) - Period(('day', Instant((2014, 2, 2)), 1)) + >>> Period((DateUnit.DAY, Instant((2014, 1, 30)), 1)).offset(3) + Period((, Instant((2014, 2, 2)), 1)) - >>> Period(("month", Instant((2014, 1, 30)), 1)).offset(3) - Period(('month', Instant((2014, 4, 30)), 1)) + >>> Period((DateUnit.MONTH, Instant((2014, 1, 30)), 1)).offset(3) + Period((, Instant((2014, 4, 30)), 1)) - >>> Period(("year", Instant((2014, 1, 30)), 1)).offset(3) - Period(('year', Instant((2017, 1, 30)), 1)) + >>> Period((DateUnit.YEAR, Instant((2014, 1, 30)), 1)).offset(3) + Period((, Instant((2017, 1, 30)), 1)) - >>> Period(("day", Instant((2021, 1, 1)), 365)).offset(-3) - Period(('day', Instant((2020, 12, 29)), 365)) + >>> Period((DateUnit.DAY, Instant((2021, 1, 1)), 365)).offset(-3) + Period((, Instant((2020, 12, 29)), 365)) - >>> Period(("month", Instant((2021, 1, 1)), 12)).offset(-3) - Period(('month', Instant((2020, 10, 1)), 12)) + >>> Period((DateUnit.MONTH, Instant((2021, 1, 1)), 12)).offset(-3) + Period((, Instant((2020, 10, 1)), 12)) - >>> Period(("year", Instant((2014, 1, 1)), 1)).offset(-3) - Period(('year', Instant((2011, 1, 1)), 1)) + >>> Period((DateUnit.YEAR, Instant((2014, 1, 1)), 1)).offset(-3) + Period((, Instant((2011, 1, 1)), 1)) - >>> Period(("day", Instant((2014, 2, 3)), 1)).offset("first-of", "month") - Period(('day', Instant((2014, 2, 1)), 1)) + >>> Period((DateUnit.DAY, Instant((2014, 2, 3)), 1)).offset("first-of", DateUnit.MONTH) + Period((, Instant((2014, 2, 1)), 1)) - >>> Period(("day", Instant((2014, 2, 3)), 1)).offset("first-of", "year") - Period(('day', Instant((2014, 1, 1)), 1)) + >>> Period((DateUnit.DAY, Instant((2014, 2, 3)), 1)).offset("first-of", DateUnit.YEAR) + Period((, Instant((2014, 1, 1)), 1)) - >>> Period(("day", Instant((2014, 2, 3)), 4)).offset("first-of", "month") - Period(('day', Instant((2014, 2, 1)), 4)) + >>> Period((DateUnit.DAY, Instant((2014, 2, 3)), 4)).offset("first-of", DateUnit.MONTH) + Period((, Instant((2014, 2, 1)), 4)) - >>> Period(("day", Instant((2014, 2, 3)), 4)).offset("first-of", "year") - Period(('day', Instant((2014, 1, 1)), 4)) + >>> Period((DateUnit.DAY, Instant((2014, 2, 3)), 4)).offset("first-of", DateUnit.YEAR) + Period((, Instant((2014, 1, 1)), 4)) - >>> Period(("month", Instant((2014, 2, 3)), 1)).offset("first-of") - Period(('month', Instant((2014, 2, 1)), 1)) + >>> Period((DateUnit.MONTH, Instant((2014, 2, 3)), 1)).offset("first-of") + Period((, Instant((2014, 2, 1)), 1)) - >>> Period(("month", Instant((2014, 2, 3)), 1)).offset("first-of", "month") - Period(('month', Instant((2014, 2, 1)), 1)) + >>> Period((DateUnit.MONTH, Instant((2014, 2, 3)), 1)).offset("first-of", DateUnit.MONTH) + Period((, Instant((2014, 2, 1)), 1)) - >>> Period(("month", Instant((2014, 2, 3)), 1)).offset("first-of", "year") - Period(('month', Instant((2014, 1, 1)), 1)) + >>> Period((DateUnit.MONTH, Instant((2014, 2, 3)), 1)).offset("first-of", DateUnit.YEAR) + Period((, Instant((2014, 1, 1)), 1)) - >>> Period(("month", Instant((2014, 2, 3)), 4)).offset("first-of") - Period(('month', Instant((2014, 2, 1)), 4)) + >>> Period((DateUnit.MONTH, Instant((2014, 2, 3)), 4)).offset("first-of") + Period((, Instant((2014, 2, 1)), 4)) - >>> Period(("month", Instant((2014, 2, 3)), 4)).offset("first-of", "month") - Period(('month', Instant((2014, 2, 1)), 4)) + >>> Period((DateUnit.MONTH, Instant((2014, 2, 3)), 4)).offset("first-of", DateUnit.MONTH) + Period((, Instant((2014, 2, 1)), 4)) - >>> Period(("month", Instant((2014, 2, 3)), 4)).offset("first-of", "year") - Period(('month', Instant((2014, 1, 1)), 4)) + >>> Period((DateUnit.MONTH, Instant((2014, 2, 3)), 4)).offset("first-of", DateUnit.YEAR) + Period((, Instant((2014, 1, 1)), 4)) - >>> Period(("year", Instant((2014, 1, 30)), 1)).offset("first-of") - Period(('year', Instant((2014, 1, 1)), 1)) + >>> Period((DateUnit.YEAR, Instant((2014, 1, 30)), 1)).offset("first-of") + Period((, Instant((2014, 1, 1)), 1)) - >>> Period(("year", Instant((2014, 1, 30)), 1)).offset("first-of", "month") - Period(('year', Instant((2014, 1, 1)), 1)) + >>> Period((DateUnit.YEAR, Instant((2014, 1, 30)), 1)).offset("first-of", DateUnit.MONTH) + Period((, Instant((2014, 1, 1)), 1)) - >>> Period(("year", Instant((2014, 1, 30)), 1)).offset("first-of", "year") - Period(('year', Instant((2014, 1, 1)), 1)) + >>> Period((DateUnit.YEAR, Instant((2014, 1, 30)), 1)).offset("first-of", DateUnit.YEAR) + Period((, Instant((2014, 1, 1)), 1)) - >>> Period(("year", Instant((2014, 2, 3)), 1)).offset("first-of") - Period(('year', Instant((2014, 1, 1)), 1)) + >>> Period((DateUnit.YEAR, Instant((2014, 2, 3)), 1)).offset("first-of") + Period((, Instant((2014, 1, 1)), 1)) - >>> Period(("year", Instant((2014, 2, 3)), 1)).offset("first-of", "month") - Period(('year', Instant((2014, 2, 1)), 1)) + >>> Period((DateUnit.YEAR, Instant((2014, 2, 3)), 1)).offset("first-of", DateUnit.MONTH) + Period((, Instant((2014, 2, 1)), 1)) - >>> Period(("year", Instant((2014, 2, 3)), 1)).offset("first-of", "year") - Period(('year', Instant((2014, 1, 1)), 1)) + >>> Period((DateUnit.YEAR, Instant((2014, 2, 3)), 1)).offset("first-of", DateUnit.YEAR) + Period((, Instant((2014, 1, 1)), 1)) - >>> Period(("day", Instant((2014, 2, 3)), 1)).offset("last-of", "month") - Period(('day', Instant((2014, 2, 28)), 1)) + >>> Period((DateUnit.DAY, Instant((2014, 2, 3)), 1)).offset("last-of", DateUnit.MONTH) + Period((, Instant((2014, 2, 28)), 1)) - >>> Period(("day", Instant((2014, 2, 3)), 1)).offset("last-of", "year") - Period(('day', Instant((2014, 12, 31)), 1)) + >>> Period((DateUnit.DAY, Instant((2014, 2, 3)), 1)).offset("last-of", DateUnit.YEAR) + Period((, Instant((2014, 12, 31)), 1)) - >>> Period(("day", Instant((2014, 2, 3)), 4)).offset("last-of", "month") - Period(('day', Instant((2014, 2, 28)), 4)) + >>> Period((DateUnit.DAY, Instant((2014, 2, 3)), 4)).offset("last-of", DateUnit.MONTH) + Period((, Instant((2014, 2, 28)), 4)) - >>> Period(("day", Instant((2014, 2, 3)), 4)).offset("last-of", "year") - Period(('day', Instant((2014, 12, 31)), 4)) + >>> Period((DateUnit.DAY, Instant((2014, 2, 3)), 4)).offset("last-of", DateUnit.YEAR) + Period((, Instant((2014, 12, 31)), 4)) - >>> Period(("month", Instant((2014, 2, 3)), 1)).offset("last-of") - Period(('month', Instant((2014, 2, 28)), 1)) + >>> Period((DateUnit.MONTH, Instant((2014, 2, 3)), 1)).offset("last-of") + Period((, Instant((2014, 2, 28)), 1)) - >>> Period(("month", Instant((2014, 2, 3)), 1)).offset("last-of", "month") - Period(('month', Instant((2014, 2, 28)), 1)) + >>> Period((DateUnit.MONTH, Instant((2014, 2, 3)), 1)).offset("last-of", DateUnit.MONTH) + Period((, Instant((2014, 2, 28)), 1)) - >>> Period(("month", Instant((2014, 2, 3)), 1)).offset("last-of", "year") - Period(('month', Instant((2014, 12, 31)), 1)) + >>> Period((DateUnit.MONTH, Instant((2014, 2, 3)), 1)).offset("last-of", DateUnit.YEAR) + Period((, Instant((2014, 12, 31)), 1)) - >>> Period(("month", Instant((2014, 2, 3)), 4)).offset("last-of") - Period(('month', Instant((2014, 2, 28)), 4)) + >>> Period((DateUnit.MONTH, Instant((2014, 2, 3)), 4)).offset("last-of") + Period((, Instant((2014, 2, 28)), 4)) - >>> Period(("month", Instant((2014, 2, 3)), 4)).offset("last-of", "month") - Period(('month', Instant((2014, 2, 28)), 4)) + >>> Period((DateUnit.MONTH, Instant((2014, 2, 3)), 4)).offset("last-of", DateUnit.MONTH) + Period((, Instant((2014, 2, 28)), 4)) - >>> Period(("month", Instant((2014, 2, 3)), 4)).offset("last-of", "year") - Period(('month', Instant((2014, 12, 31)), 4)) + >>> Period((DateUnit.MONTH, Instant((2014, 2, 3)), 4)).offset("last-of", DateUnit.YEAR) + Period((, Instant((2014, 12, 31)), 4)) - >>> Period(("year", Instant((2014, 2, 3)), 1)).offset("last-of") - Period(('year', Instant((2014, 12, 31)), 1)) + >>> Period((DateUnit.YEAR, Instant((2014, 2, 3)), 1)).offset("last-of") + Period((, Instant((2014, 12, 31)), 1)) - >>> Period(("year", Instant((2014, 1, 1)), 1)).offset("last-of", "month") - Period(('year', Instant((2014, 1, 31)), 1)) + >>> Period((DateUnit.YEAR, Instant((2014, 1, 1)), 1)).offset("last-of", DateUnit.MONTH) + Period((, Instant((2014, 1, 31)), 1)) - >>> Period(("year", Instant((2014, 2, 3)), 1)).offset("last-of", "year") - Period(('year', Instant((2014, 12, 31)), 1)) + >>> Period((DateUnit.YEAR, Instant((2014, 2, 3)), 1)).offset("last-of", DateUnit.YEAR) + Period((, Instant((2014, 12, 31)), 1)) - >>> Period(("year", Instant((2014, 2, 3)), 1)).offset("last-of") - Period(('year', Instant((2014, 12, 31)), 1)) + >>> Period((DateUnit.YEAR, Instant((2014, 2, 3)), 1)).offset("last-of") + Period((, Instant((2014, 12, 31)), 1)) - >>> Period(("year", Instant((2014, 2, 3)), 1)).offset("last-of", "month") - Period(('year', Instant((2014, 2, 28)), 1)) + >>> Period((DateUnit.YEAR, Instant((2014, 2, 3)), 1)).offset("last-of", DateUnit.MONTH) + Period((, Instant((2014, 2, 28)), 1)) - >>> Period(("year", Instant((2014, 2, 3)), 1)).offset("last-of", "year") - Period(('year', Instant((2014, 12, 31)), 1)) + >>> Period((DateUnit.YEAR, Instant((2014, 2, 3)), 1)).offset("last-of", DateUnit.YEAR) + Period((, Instant((2014, 12, 31)), 1)) """ @@ -425,9 +426,9 @@ def size(self): def size_in_months(self): """Return the size of the period in months.""" - if (self[0] == config.MONTH): + if (self[0] == DateUnit.MONTH): return self[2] - if(self[0] == config.YEAR): + if(self[0] == DateUnit.YEAR): return self[2] * 12 raise ValueError("Cannot calculate number of months in {0}".format(self[0])) @@ -437,10 +438,10 @@ def size_in_days(self): unit, instant, length = self - if unit == config.DAY: + if unit == DateUnit.DAY: return length - if unit in [config.MONTH, config.YEAR]: - last_day = self.start.offset(length, unit).offset(-1, config.DAY) + if unit in [DateUnit.MONTH, DateUnit.YEAR]: + last_day = self.start.offset(length, unit).offset(-1, DateUnit.DAY) return (last_day.date - self.start.date).days + 1 raise ValueError("Cannot calculate number of days in {0}".format(unit)) @@ -456,40 +457,40 @@ def stop(self) -> Instant: """Return the last day of the period as an Instant instance. Examples: - >>> Period(("year", Instant((2022, 1, 1)), 1)).stop + >>> Period((DateUnit.YEAR, Instant((2022, 1, 1)), 1)).stop Instant((2022, 12, 31)) - >>> Period(("month", Instant((2022, 1, 1)), 12)).stop + >>> Period((DateUnit.MONTH, Instant((2022, 1, 1)), 12)).stop Instant((2022, 12, 31)) - >>> Period(("day", Instant((2022, 1, 1)), 365)).stop + >>> Period((DateUnit.DAY, Instant((2022, 1, 1)), 365)).stop Instant((2022, 12, 31)) - >>> Period(("year", Instant((2012, 2, 29)), 1)).stop + >>> Period((DateUnit.YEAR, Instant((2012, 2, 29)), 1)).stop Instant((2013, 2, 28)) - >>> Period(("month", Instant((2012, 2, 29)), 1)).stop + >>> Period((DateUnit.MONTH, Instant((2012, 2, 29)), 1)).stop Instant((2012, 3, 28)) - >>> Period(("day", Instant((2012, 2, 29)), 1)).stop + >>> Period((DateUnit.DAY, Instant((2012, 2, 29)), 1)).stop Instant((2012, 2, 29)) - >>> Period(("year", Instant((2012, 2, 29)), 2)).stop + >>> Period((DateUnit.YEAR, Instant((2012, 2, 29)), 2)).stop Instant((2014, 2, 28)) - >>> Period(("month", Instant((2012, 2, 29)), 2)).stop + >>> Period((DateUnit.MONTH, Instant((2012, 2, 29)), 2)).stop Instant((2012, 4, 28)) - >>> Period(("day", Instant((2012, 2, 29)), 2)).stop + >>> Period((DateUnit.DAY, Instant((2012, 2, 29)), 2)).stop Instant((2012, 3, 1)) """ unit, start_instant, size = self year, month, day = start_instant - if unit == config.ETERNITY: + if unit == DateUnit.ETERNITY: return Instant((float("inf"), float("inf"), float("inf"))) - if unit == 'day': + if unit == DateUnit.DAY: if size > 1: day += size - 1 month_last_day = calendar.monthrange(year, month)[1] @@ -501,13 +502,13 @@ def stop(self) -> Instant: day -= month_last_day month_last_day = calendar.monthrange(year, month)[1] else: - if unit == 'month': + if unit == DateUnit.MONTH: month += size while month > 12: year += 1 month -= 12 else: - assert unit == 'year', 'Invalid unit: {} of type {}'.format(unit, type(unit)) + assert unit == DateUnit.YEAR, 'Invalid unit: {} of type {}'.format(unit, type(unit)) year += size day -= 1 if day < 1: @@ -534,7 +535,7 @@ def unit(self): @property def last_3_months(self): - return self.first_month.start.period('month', 3).offset(-3) + return self.first_month.start.period(DateUnit.MONTH, 3).offset(-3) @property def last_month(self): @@ -542,20 +543,20 @@ def last_month(self): @property def last_year(self): - return self.start.offset("first-of", "year").period('year').offset(-1) + return self.start.offset("first-of", DateUnit.YEAR).period(DateUnit.YEAR).offset(-1) @property def n_2(self): - return self.start.offset("first-of", "year").period('year').offset(-2) + return self.start.offset("first-of", DateUnit.YEAR).period(DateUnit.YEAR).offset(-2) @property def this_year(self): - return self.start.offset("first-of", "year").period('year') + return self.start.offset("first-of", DateUnit.YEAR).period(DateUnit.YEAR) @property def first_month(self): - return self.start.offset("first-of", "month").period('month') + return self.start.offset("first-of", DateUnit.MONTH).period(DateUnit.MONTH) @property def first_day(self): - return self.start.period('day') + return self.start.period(DateUnit.DAY) diff --git a/openfisca_core/periods/tests/test_helpers.py b/openfisca_core/periods/tests/test_helpers.py index 6dd09788b9..2095e940f3 100644 --- a/openfisca_core/periods/tests/test_helpers.py +++ b/openfisca_core/periods/tests/test_helpers.py @@ -3,14 +3,14 @@ import pytest from openfisca_core import periods -from openfisca_core.periods import Instant, Period, helpers +from openfisca_core.periods import DateUnit, Instant, Period, helpers @pytest.mark.parametrize("arg, expected", [ [None, None], [datetime.date(1, 1, 1), Instant((1, 1, 1))], [Instant((1, 1, 1)), Instant((1, 1, 1))], - [Period((periods.DAY, Instant((1, 1, 1)), 365)), Instant((1, 1, 1))], + [Period((DateUnit.DAY, Instant((1, 1, 1)), 365)), Instant((1, 1, 1))], [-1, Instant((-1, 1, 1))], [0, Instant((0, 1, 1))], [1, Instant((1, 1, 1))], @@ -24,7 +24,7 @@ [(None, None, None), Instant((None, None, None))], [(datetime.date(1, 1, 1),), Instant((datetime.date(1, 1, 1), 1, 1))], [(Instant((1, 1, 1)),), Instant((Instant((1, 1, 1)), 1, 1))], - [(Period((periods.DAY, Instant((1, 1, 1)), 365)),), Instant((Period((periods.DAY, Instant((1, 1, 1)), 365)), 1, 1))], + [(Period((DateUnit.DAY, Instant((1, 1, 1)), 365)),), Instant((Period((DateUnit.DAY, Instant((1, 1, 1)), 365)), 1, 1))], [(-1,), Instant((-1, 1, 1))], [(-1, -1), Instant((-1, -1, 1))], [(-1, -1, -1), Instant((-1, -1, -1))], @@ -39,8 +39,8 @@ def test_instant_with_a_valid_argument(arg, expected): @pytest.mark.parametrize("arg, error", [ - [periods.YEAR, ValueError], - [periods.ETERNITY, ValueError], + [DateUnit.YEAR, ValueError], + [DateUnit.ETERNITY, ValueError], ["1000-0", ValueError], ["1000-0-0", ValueError], ["1000-1", ValueError], @@ -94,39 +94,39 @@ def test_instant_date_with_an_invalid_argument(arg, error): @pytest.mark.parametrize("arg, expected", [ - ["eternity", Period((periods.ETERNITY, Instant((1, 1, 1)), float("inf")))], - ["ETERNITY", Period((periods.ETERNITY, Instant((1, 1, 1)), float("inf")))], - [periods.ETERNITY, Period((periods.ETERNITY, Instant((1, 1, 1)), float("inf")))], - [Instant((1, 1, 1)), Period((periods.DAY, Instant((1, 1, 1)), 1))], - [Period((periods.DAY, Instant((1, 1, 1)), 365)), Period((periods.DAY, Instant((1, 1, 1)), 365))], - [-1, Period((periods.YEAR, Instant((-1, 1, 1)), 1))], - [0, Period((periods.YEAR, Instant((0, 1, 1)), 1))], - [1, Period((periods.YEAR, Instant((1, 1, 1)), 1))], - [999, Period((periods.YEAR, Instant((999, 1, 1)), 1))], - [1000, Period((periods.YEAR, Instant((1000, 1, 1)), 1))], - ["1000", Period((periods.YEAR, Instant((1000, 1, 1)), 1))], - ["1000-1", Period((periods.MONTH, Instant((1000, 1, 1)), 1))], - ["1000-1-1", Period((periods.DAY, Instant((1000, 1, 1)), 1))], - ["1000-01", Period((periods.MONTH, Instant((1000, 1, 1)), 1))], - ["1000-01-01", Period((periods.DAY, Instant((1000, 1, 1)), 1))], - ["1004-02-29", Period((periods.DAY, Instant((1004, 2, 29)), 1))], - ["year:1000", Period((periods.YEAR, Instant((1000, 1, 1)), 1))], - ["year:1000-01", Period((periods.YEAR, Instant((1000, 1, 1)), 1))], - ["year:1000-01-01", Period((periods.YEAR, Instant((1000, 1, 1)), 1))], - ["year:1000:1", Period((periods.YEAR, Instant((1000, 1, 1)), 1))], - ["year:1000-01:1", Period((periods.YEAR, Instant((1000, 1, 1)), 1))], - ["year:1000-01-01:1", Period((periods.YEAR, Instant((1000, 1, 1)), 1))], - ["year:1000:3", Period((periods.YEAR, Instant((1000, 1, 1)), 3))], - ["year:1000-01:3", Period((periods.YEAR, Instant((1000, 1, 1)), 3))], - ["month:1000-01-01:3", Period((periods.MONTH, Instant((1000, 1, 1)), 3))], - ["month:1000-01", Period((periods.MONTH, Instant((1000, 1, 1)), 1))], - ["month:1000-01-01", Period((periods.MONTH, Instant((1000, 1, 1)), 1))], - ["month:1000-01:1", Period((periods.MONTH, Instant((1000, 1, 1)), 1))], - ["month:1000-01:3", Period((periods.MONTH, Instant((1000, 1, 1)), 3))], - ["month:1000-01-01:3", Period((periods.MONTH, Instant((1000, 1, 1)), 3))], - ["month:1000-01-01:3", Period((periods.MONTH, Instant((1000, 1, 1)), 3))], - ["day:1000-01-01", Period((periods.DAY, Instant((1000, 1, 1)), 1))], - ["day:1000-01-01:3", Period((periods.DAY, Instant((1000, 1, 1)), 3))], + ["eternity", Period((DateUnit.ETERNITY, Instant((1, 1, 1)), float("inf")))], + ["ETERNITY", Period((DateUnit.ETERNITY, Instant((1, 1, 1)), float("inf")))], + [DateUnit.ETERNITY, Period((DateUnit.ETERNITY, Instant((1, 1, 1)), float("inf")))], + [Instant((1, 1, 1)), Period((DateUnit.DAY, Instant((1, 1, 1)), 1))], + [Period((DateUnit.DAY, Instant((1, 1, 1)), 365)), Period((DateUnit.DAY, Instant((1, 1, 1)), 365))], + [-1, Period((DateUnit.YEAR, Instant((-1, 1, 1)), 1))], + [0, Period((DateUnit.YEAR, Instant((0, 1, 1)), 1))], + [1, Period((DateUnit.YEAR, Instant((1, 1, 1)), 1))], + [999, Period((DateUnit.YEAR, Instant((999, 1, 1)), 1))], + [1000, Period((DateUnit.YEAR, Instant((1000, 1, 1)), 1))], + ["1000", Period((DateUnit.YEAR, Instant((1000, 1, 1)), 1))], + ["1000-1", Period((DateUnit.MONTH, Instant((1000, 1, 1)), 1))], + ["1000-1-1", Period((DateUnit.DAY, Instant((1000, 1, 1)), 1))], + ["1000-01", Period((DateUnit.MONTH, Instant((1000, 1, 1)), 1))], + ["1000-01-01", Period((DateUnit.DAY, Instant((1000, 1, 1)), 1))], + ["1004-02-29", Period((DateUnit.DAY, Instant((1004, 2, 29)), 1))], + ["year:1000", Period((DateUnit.YEAR, Instant((1000, 1, 1)), 1))], + ["year:1000-01", Period((DateUnit.YEAR, Instant((1000, 1, 1)), 1))], + ["year:1000-01-01", Period((DateUnit.YEAR, Instant((1000, 1, 1)), 1))], + ["year:1000:1", Period((DateUnit.YEAR, Instant((1000, 1, 1)), 1))], + ["year:1000-01:1", Period((DateUnit.YEAR, Instant((1000, 1, 1)), 1))], + ["year:1000-01-01:1", Period((DateUnit.YEAR, Instant((1000, 1, 1)), 1))], + ["year:1000:3", Period((DateUnit.YEAR, Instant((1000, 1, 1)), 3))], + ["year:1000-01:3", Period((DateUnit.YEAR, Instant((1000, 1, 1)), 3))], + ["month:1000-01-01:3", Period((DateUnit.MONTH, Instant((1000, 1, 1)), 3))], + ["month:1000-01", Period((DateUnit.MONTH, Instant((1000, 1, 1)), 1))], + ["month:1000-01-01", Period((DateUnit.MONTH, Instant((1000, 1, 1)), 1))], + ["month:1000-01:1", Period((DateUnit.MONTH, Instant((1000, 1, 1)), 1))], + ["month:1000-01:3", Period((DateUnit.MONTH, Instant((1000, 1, 1)), 3))], + ["month:1000-01-01:3", Period((DateUnit.MONTH, Instant((1000, 1, 1)), 3))], + ["month:1000-01-01:3", Period((DateUnit.MONTH, Instant((1000, 1, 1)), 3))], + ["day:1000-01-01", Period((DateUnit.DAY, Instant((1000, 1, 1)), 1))], + ["day:1000-01-01:3", Period((DateUnit.DAY, Instant((1000, 1, 1)), 3))], ]) def test_period_with_a_valid_argument(arg, expected): assert periods.period(arg) == expected @@ -134,7 +134,7 @@ def test_period_with_a_valid_argument(arg, expected): @pytest.mark.parametrize("arg, error", [ [None, ValueError], - [periods.YEAR, ValueError], + [DateUnit.YEAR, ValueError], [datetime.date(1, 1, 1), ValueError], ["1000-0", ValueError], ["1000-13", ValueError], @@ -165,7 +165,7 @@ def test_period_with_a_valid_argument(arg, expected): [(None, None, None, None), ValueError], [(datetime.date(1, 1, 1),), ValueError], [(Instant((1, 1, 1)),), ValueError], - [(Period((periods.DAY, Instant((1, 1, 1)), 365)),), ValueError], + [(Period((DateUnit.DAY, Instant((1, 1, 1)), 365)),), ValueError], [(1,), ValueError], [(1, 1), ValueError], [(1, 1, 1), ValueError], @@ -186,12 +186,12 @@ def test_period_with_an_invalid_argument(arg, error): @pytest.mark.parametrize("arg, expected", [ ["1", None], ["999", None], - ["1000", Period((periods.YEAR, Instant((1000, 1, 1)), 1))], - ["1000-1", Period((periods.MONTH, Instant((1000, 1, 1)), 1))], - ["1000-01", Period((periods.MONTH, Instant((1000, 1, 1)), 1))], - ["1000-1-1", Period((periods.DAY, Instant((1000, 1, 1)), 1))], - ["1000-01-1", Period((periods.DAY, Instant((1000, 1, 1)), 1))], - ["1000-01-01", Period((periods.DAY, Instant((1000, 1, 1)), 1))], + ["1000", Period((DateUnit.YEAR, Instant((1000, 1, 1)), 1))], + ["1000-1", Period((DateUnit.MONTH, Instant((1000, 1, 1)), 1))], + ["1000-01", Period((DateUnit.MONTH, Instant((1000, 1, 1)), 1))], + ["1000-1-1", Period((DateUnit.DAY, Instant((1000, 1, 1)), 1))], + ["1000-01-1", Period((DateUnit.DAY, Instant((1000, 1, 1)), 1))], + ["1000-01-01", Period((DateUnit.DAY, Instant((1000, 1, 1)), 1))], ["1000-01-99", None], ]) def test__parse_simple_period_with_a_valid_argument(arg, expected): @@ -199,12 +199,12 @@ def test__parse_simple_period_with_a_valid_argument(arg, expected): @pytest.mark.parametrize("arg, expected", [ - [Period((periods.DAY, Instant((1, 1, 1)), 365)), "100_365"], - [Period((periods.MONTH, Instant((1, 1, 1)), 12)), "200_12"], - [Period((periods.YEAR, Instant((1, 1, 1)), 2)), "300_2"], - [Period((periods.ETERNITY, Instant((1, 1, 1)), 1)), "400_1"], - [(periods.DAY, None, 1), "100_1"], - [(periods.MONTH, None, -1000), "200_-1000"], + [Period((DateUnit.DAY, Instant((1, 1, 1)), 365)), "100_365"], + [Period((DateUnit.MONTH, Instant((1, 1, 1)), 12)), "200_12"], + [Period((DateUnit.YEAR, Instant((1, 1, 1)), 2)), "300_2"], + [Period((DateUnit.ETERNITY, Instant((1, 1, 1)), 1)), "400_1"], + [(DateUnit.DAY, None, 1), "100_1"], + [(DateUnit.MONTH, None, -1000), "200_-1000"], ]) def test_key_period_size_with_a_valid_argument(arg, expected): assert periods.key_period_size(arg) == expected diff --git a/openfisca_core/periods/tests/test_period.py b/openfisca_core/periods/tests/test_period.py index 4aab4d3339..dbc846af26 100644 --- a/openfisca_core/periods/tests/test_period.py +++ b/openfisca_core/periods/tests/test_period.py @@ -1,47 +1,47 @@ import pytest from openfisca_core import periods -from openfisca_core.periods import Instant, Period +from openfisca_core.periods import DateUnit, Instant, Period @pytest.mark.parametrize("date_unit, instant, size, expected", [ - [periods.YEAR, Instant((2022, 1, 1)), 1, "2022"], - [periods.MONTH, Instant((2022, 1, 1)), 12, "2022"], - [periods.YEAR, Instant((2022, 3, 1)), 1, "year:2022-03"], - [periods.MONTH, Instant((2022, 3, 1)), 12, "year:2022-03"], - [periods.YEAR, Instant((2022, 1, 1)), 3, "year:2022:3"], - [periods.YEAR, Instant((2022, 1, 3)), 3, "year:2022:3"], + [DateUnit.YEAR, Instant((2022, 1, 1)), 1, "2022"], + [DateUnit.MONTH, Instant((2022, 1, 1)), 12, "2022"], + [DateUnit.YEAR, Instant((2022, 3, 1)), 1, "year:2022-03"], + [DateUnit.MONTH, Instant((2022, 3, 1)), 12, "year:2022-03"], + [DateUnit.YEAR, Instant((2022, 1, 1)), 3, "year:2022:3"], + [DateUnit.YEAR, Instant((2022, 1, 3)), 3, "year:2022:3"], ]) def test_str_with_years(date_unit, instant, size, expected): assert str(Period((date_unit, instant, size))) == expected @pytest.mark.parametrize("date_unit, instant, size, expected", [ - [periods.MONTH, Instant((2022, 1, 1)), 1, "2022-01"], - [periods.MONTH, Instant((2022, 1, 1)), 3, "month:2022-01:3"], - [periods.MONTH, Instant((2022, 3, 1)), 3, "month:2022-03:3"], + [DateUnit.MONTH, Instant((2022, 1, 1)), 1, "2022-01"], + [DateUnit.MONTH, Instant((2022, 1, 1)), 3, "month:2022-01:3"], + [DateUnit.MONTH, Instant((2022, 3, 1)), 3, "month:2022-03:3"], ]) def test_str_with_months(date_unit, instant, size, expected): assert str(Period((date_unit, instant, size))) == expected @pytest.mark.parametrize("date_unit, instant, size, expected", [ - [periods.DAY, Instant((2022, 1, 1)), 1, "2022-01-01"], - [periods.DAY, Instant((2022, 1, 1)), 3, "day:2022-01-01:3"], - [periods.DAY, Instant((2022, 3, 1)), 3, "day:2022-03-01:3"], + [DateUnit.DAY, Instant((2022, 1, 1)), 1, "2022-01-01"], + [DateUnit.DAY, Instant((2022, 1, 1)), 3, "day:2022-01-01:3"], + [DateUnit.DAY, Instant((2022, 3, 1)), 3, "day:2022-03-01:3"], ]) def test_str_with_days(date_unit, instant, size, expected): assert str(Period((date_unit, instant, size))) == expected @pytest.mark.parametrize("period, unit, length, first, last", [ - (periods.period('year:2014:2'), periods.YEAR, 2, periods.period('2014'), periods.period('2015')), - (periods.period(2017), periods.MONTH, 12, periods.period('2017-01'), periods.period('2017-12')), - (periods.period('year:2014:2'), periods.MONTH, 24, periods.period('2014-01'), periods.period('2015-12')), - (periods.period('month:2014-03:3'), periods.MONTH, 3, periods.period('2014-03'), periods.period('2014-05')), - (periods.period(2017), periods.DAY, 365, periods.period('2017-01-01'), periods.period('2017-12-31')), - (periods.period('year:2014:2'), periods.DAY, 730, periods.period('2014-01-01'), periods.period('2015-12-31')), - (periods.period('month:2014-03:3'), periods.DAY, 92, periods.period('2014-03-01'), periods.period('2014-05-31')), + (periods.period('year:2014:2'), DateUnit.YEAR, 2, periods.period('2014'), periods.period('2015')), + (periods.period(2017), DateUnit.MONTH, 12, periods.period('2017-01'), periods.period('2017-12')), + (periods.period('year:2014:2'), DateUnit.MONTH, 24, periods.period('2014-01'), periods.period('2015-12')), + (periods.period('month:2014-03:3'), DateUnit.MONTH, 3, periods.period('2014-03'), periods.period('2014-05')), + (periods.period(2017), DateUnit.DAY, 365, periods.period('2017-01-01'), periods.period('2017-12-31')), + (periods.period('year:2014:2'), DateUnit.DAY, 730, periods.period('2014-01-01'), periods.period('2015-12-31')), + (periods.period('month:2014-03:3'), DateUnit.DAY, 92, periods.period('2014-03-01'), periods.period('2014-05-31')), ]) def test_subperiods(period, unit, length, first, last): subperiods = period.get_subperiods(unit) @@ -51,13 +51,13 @@ def test_subperiods(period, unit, length, first, last): @pytest.mark.parametrize("date_unit, instant, size, expected", [ - [periods.MONTH, Instant((2022, 12, 1)), 1, 1], - [periods.MONTH, Instant((2012, 2, 3)), 1, 1], - [periods.MONTH, Instant((2022, 1, 3)), 3, 3], - [periods.MONTH, Instant((2012, 1, 3)), 3, 3], - [periods.YEAR, Instant((2022, 12, 1)), 1, 12], - [periods.YEAR, Instant((2012, 1, 1)), 1, 12], - [periods.YEAR, Instant((2022, 1, 1)), 2, 24], + [DateUnit.MONTH, Instant((2022, 12, 1)), 1, 1], + [DateUnit.MONTH, Instant((2012, 2, 3)), 1, 1], + [DateUnit.MONTH, Instant((2022, 1, 3)), 3, 3], + [DateUnit.MONTH, Instant((2012, 1, 3)), 3, 3], + [DateUnit.YEAR, Instant((2022, 12, 1)), 1, 12], + [DateUnit.YEAR, Instant((2012, 1, 1)), 1, 12], + [DateUnit.YEAR, Instant((2022, 1, 1)), 2, 24], ]) def test_day_size_in_months(date_unit, instant, size, expected): period = Period((date_unit, instant, size)) @@ -65,15 +65,15 @@ def test_day_size_in_months(date_unit, instant, size, expected): @pytest.mark.parametrize("date_unit, instant, size, expected", [ - [periods.DAY, Instant((2022, 12, 31)), 1, 1], - [periods.DAY, Instant((2022, 12, 31)), 3, 3], - [periods.MONTH, Instant((2022, 12, 1)), 1, 31], - [periods.MONTH, Instant((2012, 2, 3)), 1, 29], - [periods.MONTH, Instant((2022, 1, 3)), 3, 31 + 28 + 31], - [periods.MONTH, Instant((2012, 1, 3)), 3, 31 + 29 + 31], - [periods.YEAR, Instant((2022, 12, 1)), 1, 365], - [periods.YEAR, Instant((2012, 1, 1)), 1, 366], - [periods.YEAR, Instant((2022, 1, 1)), 2, 730], + [DateUnit.DAY, Instant((2022, 12, 31)), 1, 1], + [DateUnit.DAY, Instant((2022, 12, 31)), 3, 3], + [DateUnit.MONTH, Instant((2022, 12, 1)), 1, 31], + [DateUnit.MONTH, Instant((2012, 2, 3)), 1, 29], + [DateUnit.MONTH, Instant((2022, 1, 3)), 3, 31 + 28 + 31], + [DateUnit.MONTH, Instant((2012, 1, 3)), 3, 31 + 29 + 31], + [DateUnit.YEAR, Instant((2022, 12, 1)), 1, 365], + [DateUnit.YEAR, Instant((2012, 1, 1)), 1, 366], + [DateUnit.YEAR, Instant((2022, 1, 1)), 2, 730], ]) def test_day_size_in_days(date_unit, instant, size, expected): period = Period((date_unit, instant, size)) diff --git a/openfisca_core/scripts/measure_performances.py b/openfisca_core/scripts/measure_performances.py index 1d84ddd585..a3a56c0aff 100644 --- a/openfisca_core/scripts/measure_performances.py +++ b/openfisca_core/scripts/measure_performances.py @@ -13,7 +13,7 @@ from numpy.core.defchararray import startswith from openfisca_core import periods, simulations -from openfisca_core.periods import ETERNITY +from openfisca_core.periods import DateUnit from openfisca_core.entities import build_entity from openfisca_core.variables import Variable from openfisca_core.taxbenefitsystems import TaxBenefitSystem @@ -82,7 +82,7 @@ class city_code(Variable): value_type = 'FixedStr' max_length = 5 entity = Famille - definition_period = ETERNITY + definition_period = DateUnit.ETERNITY label = """Code INSEE "city_code" de la commune de résidence de la famille""" @@ -115,7 +115,7 @@ class dom_tom(Variable): label = "La famille habite-t-elle les DOM-TOM ?" def formula(self, simulation, period): - period = period.start.period('year').offset('first-of') + period = period.start.period(DateUnit.YEAR).offset('first-of') city_code = simulation.calculate('city_code', period) return np.logical_or(startswith(city_code, '97'), startswith(city_code, '98')) @@ -126,7 +126,7 @@ class revenu_disponible(Variable): label = "Revenu disponible de l'individu" def formula(self, simulation, period): - period = period.start.period('year').offset('first-of') + period = period.start.period(DateUnit.YEAR).offset('first-of') rsa = simulation.calculate('rsa', period) salaire_imposable = simulation.calculate('salaire_imposable', period) return rsa + salaire_imposable * 0.7 @@ -138,17 +138,17 @@ class rsa(Variable): label = "RSA" def formula_2010_01_01(self, simulation, period): - period = period.start.period('month').offset('first-of') + period = period.start.period(DateUnit.MONTH).offset('first-of') salaire_imposable = simulation.calculate('salaire_imposable', period) return (salaire_imposable < 500) * 100.0 def formula_2011_01_01(self, simulation, period): - period = period.start.period('month').offset('first-of') + period = period.start.period(DateUnit.MONTH).offset('first-of') salaire_imposable = simulation.calculate('salaire_imposable', period) return (salaire_imposable < 500) * 200.0 def formula_2013_01_01(self, simulation, period): - period = period.start.period('month').offset('first-of') + period = period.start.period(DateUnit.MONTH).offset('first-of') salaire_imposable = simulation.calculate('salaire_imposable', period) return (salaire_imposable < 500) * 300 @@ -159,7 +159,7 @@ class salaire_imposable(Variable): label = "Salaire imposable" def formula(individu, period): - period = period.start.period('year').offset('first-of') + period = period.start.period(DateUnit.YEAR).offset('first-of') dom_tom = individu.famille('dom_tom', period) salaire_net = individu('salaire_net', period) return salaire_net * 0.9 - 100 * dom_tom @@ -171,7 +171,7 @@ class salaire_net(Variable): label = "Salaire net" def formula(self, simulation, period): - period = period.start.period('year').offset('first-of') + period = period.start.period(DateUnit.YEAR).offset('first-of') salaire_brut = simulation.calculate('salaire_brut', period) return salaire_brut * 0.8 diff --git a/openfisca_core/scripts/measure_performances_fancy_indexing.py b/openfisca_core/scripts/measure_performances_fancy_indexing.py index 894250ef54..69d8cea1be 100644 --- a/openfisca_core/scripts/measure_performances_fancy_indexing.py +++ b/openfisca_core/scripts/measure_performances_fancy_indexing.py @@ -1,9 +1,10 @@ # flake8: noqa T001 -import numpy as np import timeit + +import numpy as np + from openfisca_france import CountryTaxBenefitSystem -from openfisca_core.model_api import * # noqa analysis:ignore tbs = CountryTaxBenefitSystem() diff --git a/openfisca_core/simulations/simulation.py b/openfisca_core/simulations/simulation.py index 5dd2694292..8bd2497c50 100644 --- a/openfisca_core/simulations/simulation.py +++ b/openfisca_core/simulations/simulation.py @@ -6,7 +6,7 @@ from openfisca_core import commons, periods from openfisca_core.errors import CycleError, SpiralError from openfisca_core.indexed_enums import Enum, EnumArray -from openfisca_core.periods import Period +from openfisca_core.periods import DateUnit, Period from openfisca_core.tracers import FullTracer, SimpleTracer, TracingParameterNodeAtInstant from openfisca_core.warnings import TempfileWarning @@ -159,7 +159,7 @@ def calculate_add(self, variable_name, period): variable.definition_period )) - if variable.definition_period not in [periods.DAY, periods.MONTH, periods.YEAR]: + if variable.definition_period not in [DateUnit.DAY, DateUnit.MONTH, DateUnit.YEAR]: raise ValueError("Unable to sum constant variable '{}' over period {}: only variables defined daily, monthly, or yearly can be summed over time.".format( variable.name, period)) @@ -176,7 +176,7 @@ def calculate_divide(self, variable_name, period): period = periods.period(period) # Check that the requested period matches definition_period - if variable.definition_period != periods.YEAR: + if variable.definition_period != DateUnit.YEAR: raise ValueError("Unable to divide the value of '{}' over time on period {}: only variables defined yearly can be divided over time.".format( variable_name, period)) @@ -184,10 +184,10 @@ def calculate_divide(self, variable_name, period): if period.size != 1: raise ValueError("DIVIDE option can only be used for a one-year or a one-month requested period") - if period.unit == periods.MONTH: + if period.unit == DateUnit.MONTH: computation_period = period.this_year return self.calculate(variable_name, period = computation_period) / 12. - elif period.unit == periods.YEAR: + elif period.unit == DateUnit.YEAR: return self.calculate(variable_name, period) raise ValueError("Unable to divide the value of '{}' to match period {}.".format( @@ -237,16 +237,16 @@ def _check_period_consistency(self, period, variable): """ Check that a period matches the variable definition_period """ - if variable.definition_period == periods.ETERNITY: + if variable.definition_period == DateUnit.ETERNITY: return # For variables which values are constant in time, all periods are accepted - if variable.definition_period == periods.MONTH and period.unit != periods.MONTH: + if variable.definition_period == DateUnit.MONTH and period.unit != DateUnit.MONTH: raise ValueError("Unable to compute variable '{0}' for period {1}: '{0}' must be computed for a whole month. You can use the ADD option to sum '{0}' over the requested period, or change the requested period to 'period.first_month'.".format( variable.name, period )) - if variable.definition_period == periods.YEAR and period.unit != periods.YEAR: + if variable.definition_period == DateUnit.YEAR and period.unit != DateUnit.YEAR: raise ValueError("Unable to compute variable '{0}' for period {1}: '{0}' must be computed for a whole year. You can use the DIVIDE option to get an estimate of {0} by dividing the yearly value by 12, or change the requested period to 'period.this_year'.".format( variable.name, period @@ -256,7 +256,7 @@ def _check_period_consistency(self, period, variable): raise ValueError("Unable to compute variable '{0}' for period {1}: '{0}' must be computed for a whole {2}. You can use the ADD option to sum '{0}' over the requested period.".format( variable.name, period, - 'month' if variable.definition_period == periods.MONTH else 'year' + DateUnit.MONTH if variable.definition_period == DateUnit.MONTH else DateUnit.YEAR )) def _cast_formula_result(self, value, variable): diff --git a/openfisca_core/tools/simulation_dumper.py b/openfisca_core/tools/simulation_dumper.py index 4b5907c0ff..aff2377dcd 100644 --- a/openfisca_core/tools/simulation_dumper.py +++ b/openfisca_core/tools/simulation_dumper.py @@ -7,7 +7,7 @@ from openfisca_core.simulations import Simulation from openfisca_core.data_storage import OnDiskStorage -from openfisca_core.periods import ETERNITY +from openfisca_core.periods import DateUnit def dump_simulation(simulation, directory): @@ -116,7 +116,7 @@ def _restore_entity(population, directory): def _restore_holder(simulation, variable, directory): storage_dir = os.path.join(directory, variable) - is_variable_eternal = simulation.tax_benefit_system.get_variable(variable).definition_period == ETERNITY + is_variable_eternal = simulation.tax_benefit_system.get_variable(variable).definition_period == DateUnit.ETERNITY disk_storage = OnDiskStorage( storage_dir, is_eternal = is_variable_eternal, diff --git a/openfisca_core/variables/variable.py b/openfisca_core/variables/variable.py index 7d13e5da24..e5ada23407 100644 --- a/openfisca_core/variables/variable.py +++ b/openfisca_core/variables/variable.py @@ -9,7 +9,7 @@ from openfisca_core import periods, tools from openfisca_core.entities import Entity from openfisca_core.indexed_enums import Enum, EnumArray -from openfisca_core.periods import Period +from openfisca_core.periods import DateUnit, Period from . import config, helpers @@ -34,7 +34,7 @@ class Variable: .. attribute:: definition_period - `Period `_ the variable is defined for. Possible value: ``MONTH``, ``YEAR``, ``ETERNITY``. + `Period `_ the variable is defined for. Possible value: ``DateUnit.DAY``, ``DateUnit.MONTH``, ``DateUnit.YEAR``, ``DateUnit.ETERNITY``. .. attribute:: formulas @@ -115,7 +115,7 @@ def __init__(self, baseline_variable = None): else: self.default_value = self.set(attr, 'default_value', allowed_type = self.value_type, default = config.VALUE_TYPES[self.value_type].get('default')) self.entity = self.set(attr, 'entity', required = True, setter = self.set_entity) - self.definition_period = self.set(attr, 'definition_period', required = True, allowed_values = (periods.DAY, periods.MONTH, periods.YEAR, periods.ETERNITY)) + self.definition_period = self.set(attr, 'definition_period', required = True, allowed_values = (DateUnit.DAY, DateUnit.MONTH, DateUnit.YEAR, DateUnit.ETERNITY)) self.label = self.set(attr, 'label', allowed_type = str, setter = self.set_label) self.end = self.set(attr, 'end', allowed_type = str, setter = self.set_end) self.reference = self.set(attr, 'reference', setter = self.set_reference) diff --git a/setup.py b/setup.py index 9a2e9125c0..e88629416d 100644 --- a/setup.py +++ b/setup.py @@ -19,6 +19,7 @@ 'pytest >= 4.4.1, < 6.0.0', # For openfisca test 'PyYAML >= 3.10', 'sortedcontainers == 2.2.2', + 'StrEnum >= 0.4.8, < 0.5.0', # 3.11.x backport 'typing-extensions == 3.10.0.2', ] diff --git a/tests/core/parameters_fancy_indexing/test_fancy_indexing.py b/tests/core/parameters_fancy_indexing/test_fancy_indexing.py index d34eb00773..fcdd25c093 100644 --- a/tests/core/parameters_fancy_indexing/test_fancy_indexing.py +++ b/tests/core/parameters_fancy_indexing/test_fancy_indexing.py @@ -7,9 +7,10 @@ import pytest -from openfisca_core.tools import assert_near from openfisca_core.parameters import ParameterNode, Parameter, ParameterNotFound -from openfisca_core.model_api import * # noqa +from openfisca_core.indexed_enums import Enum +from openfisca_core.tools import assert_near + LOCAL_DIR = os.path.dirname(os.path.abspath(__file__)) diff --git a/tests/core/test_calculate_output.py b/tests/core/test_calculate_output.py index 6a11a27d84..d3eb5c6666 100644 --- a/tests/core/test_calculate_output.py +++ b/tests/core/test_calculate_output.py @@ -2,27 +2,28 @@ from openfisca_country_template import entities, situation_examples -from openfisca_core import periods, simulations, tools +from openfisca_core import simulations, tools +from openfisca_core.periods import DateUnit from openfisca_core.simulations import SimulationBuilder from openfisca_core.variables import Variable class simple_variable(Variable): entity = entities.Person - definition_period = periods.MONTH + definition_period = DateUnit.MONTH value_type = int class variable_with_calculate_output_add(Variable): entity = entities.Person - definition_period = periods.MONTH + definition_period = DateUnit.MONTH value_type = int calculate_output = simulations.calculate_output_add class variable_with_calculate_output_divide(Variable): entity = entities.Person - definition_period = periods.YEAR + definition_period = DateUnit.YEAR value_type = int calculate_output = simulations.calculate_output_divide diff --git a/tests/core/test_countries.py b/tests/core/test_countries.py index aeb4d762c7..f8f359fd2d 100644 --- a/tests/core/test_countries.py +++ b/tests/core/test_countries.py @@ -2,6 +2,7 @@ from openfisca_core import periods, populations, tools from openfisca_core.errors import VariableNameConflictError, VariableNotFoundError +from openfisca_core.periods import DateUnit from openfisca_core.simulations import SimulationBuilder from openfisca_core.variables import Variable @@ -102,7 +103,7 @@ def test_variable_with_reference(make_simulation, isolated_tax_benefit_system): assert result > 0 class disposable_income(Variable): - definition_period = periods.MONTH + definition_period = DateUnit.MONTH def formula(household, period): return household.empty_array() @@ -119,7 +120,7 @@ def test_variable_name_conflict(tax_benefit_system): class disposable_income(Variable): reference = "disposable_income" - definition_period = periods.MONTH + definition_period = DateUnit.MONTH def formula(household, period): return household.empty_array() diff --git a/tests/core/test_cycles.py b/tests/core/test_cycles.py index 1c4361ded2..0def1c5953 100644 --- a/tests/core/test_cycles.py +++ b/tests/core/test_cycles.py @@ -4,6 +4,7 @@ from openfisca_core import periods, tools from openfisca_core.errors import CycleError +from openfisca_core.periods import DateUnit from openfisca_core.simulations import SimulationBuilder from openfisca_core.variables import Variable @@ -22,7 +23,7 @@ def simulation(tax_benefit_system): class variable1(Variable): value_type = int entity = entities.Person - definition_period = periods.MONTH + definition_period = DateUnit.MONTH def formula(person, period): return person('variable2', period) @@ -31,7 +32,7 @@ def formula(person, period): class variable2(Variable): value_type = int entity = entities.Person - definition_period = periods.MONTH + definition_period = DateUnit.MONTH def formula(person, period): return person('variable1', period) @@ -41,7 +42,7 @@ def formula(person, period): class variable3(Variable): value_type = int entity = entities.Person - definition_period = periods.MONTH + definition_period = DateUnit.MONTH def formula(person, period): return person('variable4', period.last_month) @@ -50,7 +51,7 @@ def formula(person, period): class variable4(Variable): value_type = int entity = entities.Person - definition_period = periods.MONTH + definition_period = DateUnit.MONTH def formula(person, period): return person('variable3', period) @@ -61,7 +62,7 @@ def formula(person, period): class variable5(Variable): value_type = int entity = entities.Person - definition_period = periods.MONTH + definition_period = DateUnit.MONTH def formula(person, period): variable6 = person('variable6', period.last_month) @@ -71,7 +72,7 @@ def formula(person, period): class variable6(Variable): value_type = int entity = entities.Person - definition_period = periods.MONTH + definition_period = DateUnit.MONTH def formula(person, period): variable5 = person('variable5', period) @@ -81,7 +82,7 @@ def formula(person, period): class variable7(Variable): value_type = int entity = entities.Person - definition_period = periods.MONTH + definition_period = DateUnit.MONTH def formula(person, period): variable5 = person('variable5', period) @@ -92,7 +93,7 @@ def formula(person, period): class cotisation(Variable): value_type = int entity = entities.Person - definition_period = periods.MONTH + definition_period = DateUnit.MONTH def formula(person, period): if period.start.month == 12: diff --git a/tests/core/test_formulas.py b/tests/core/test_formulas.py index 8851671755..527fb21d2a 100644 --- a/tests/core/test_formulas.py +++ b/tests/core/test_formulas.py @@ -2,7 +2,8 @@ from openfisca_country_template import entities -from openfisca_core import commons, periods +from openfisca_core import commons +from openfisca_core.periods import DateUnit from openfisca_core.simulations import SimulationBuilder from openfisca_core.variables import Variable @@ -12,14 +13,14 @@ class choice(Variable): value_type = int entity = entities.Person - definition_period = periods.MONTH + definition_period = DateUnit.MONTH class uses_multiplication(Variable): value_type = int entity = entities.Person label = 'Variable with formula that uses multiplication' - definition_period = periods.MONTH + definition_period = DateUnit.MONTH def formula(person, period): choice = person('choice', period) @@ -31,7 +32,7 @@ class returns_scalar(Variable): value_type = int entity = entities.Person label = 'Variable with formula that returns a scalar value' - definition_period = periods.MONTH + definition_period = DateUnit.MONTH def formula(person, period): return 666 @@ -41,7 +42,7 @@ class uses_switch(Variable): value_type = int entity = entities.Person label = 'Variable with formula that uses switch' - definition_period = periods.MONTH + definition_period = DateUnit.MONTH def formula(person, period): choice = person('choice', period) @@ -106,7 +107,7 @@ def test_group_encapsulation(): """ from openfisca_core.taxbenefitsystems import TaxBenefitSystem from openfisca_core.entities import build_entity - from openfisca_core.periods import ETERNITY + from openfisca_core.periods import DateUnit person_entity = build_entity( key="person", @@ -143,12 +144,12 @@ def test_group_encapsulation(): class household_level_variable(Variable): value_type = int entity = household_entity - definition_period = ETERNITY + definition_period = DateUnit.ETERNITY class projected_family_level_variable(Variable): value_type = int entity = family_entity - definition_period = ETERNITY + definition_period = DateUnit.ETERNITY def formula(family, period): return family.household("household_level_variable", period) diff --git a/tests/core/test_holders.py b/tests/core/test_holders.py index 907aefceb5..231222c465 100644 --- a/tests/core/test_holders.py +++ b/tests/core/test_holders.py @@ -8,6 +8,7 @@ from openfisca_core import holders, periods, tools from openfisca_core.errors import PeriodMismatchError from openfisca_core.memory_config import MemoryConfig +from openfisca_core.periods import DateUnit from openfisca_core.simulations import SimulationBuilder from openfisca_core.holders import Holder @@ -89,9 +90,9 @@ def test_permanent_variable_filled(single): simulation = single holder = simulation.person.get_holder('birth') value = numpy.asarray(['1980-01-01'], dtype = holder.variable.dtype) - holder.set_input(periods.period(periods.ETERNITY), value) + holder.set_input(periods.period(DateUnit.ETERNITY), value) assert holder.get_array(None) == value - assert holder.get_array(periods.ETERNITY) == value + assert holder.get_array(DateUnit.ETERNITY) == value assert holder.get_array('2016-01') == value diff --git a/tests/core/test_opt_out_cache.py b/tests/core/test_opt_out_cache.py index b4eab3e5a5..c28322f468 100644 --- a/tests/core/test_opt_out_cache.py +++ b/tests/core/test_opt_out_cache.py @@ -3,7 +3,7 @@ from openfisca_country_template.entities import Person from openfisca_core import periods -from openfisca_core.periods import MONTH +from openfisca_core.periods import DateUnit from openfisca_core.variables import Variable @@ -14,14 +14,14 @@ class input(Variable): value_type = int entity = Person label = "Input variable" - definition_period = MONTH + definition_period = DateUnit.MONTH class intermediate(Variable): value_type = int entity = Person label = "Intermediate result that don't need to be cached" - definition_period = MONTH + definition_period = DateUnit.MONTH def formula(person, period): return person('input', period) @@ -31,7 +31,7 @@ class output(Variable): value_type = int entity = Person label = 'Output variable' - definition_period = MONTH + definition_period = DateUnit.MONTH def formula(person, period): return person('intermediate', period) diff --git a/tests/core/test_projectors.py b/tests/core/test_projectors.py index 32635e2571..955a2e627c 100644 --- a/tests/core/test_projectors.py +++ b/tests/core/test_projectors.py @@ -1,8 +1,11 @@ +import numpy as np + +from openfisca_core.entities import build_entity +from openfisca_core.indexed_enums import Enum +from openfisca_core.periods import DateUnit from openfisca_core.simulations.simulation_builder import SimulationBuilder from openfisca_core.taxbenefitsystems import TaxBenefitSystem -from openfisca_core.entities import build_entity -from openfisca_core.model_api import Enum, Variable, ETERNITY -import numpy as np +from openfisca_core.variables import Variable def test_shortcut_to_containing_entity_provided(): @@ -125,14 +128,14 @@ class household_enum_variable(Variable): possible_values = enum default_value = enum.FIRST_OPTION entity = household - definition_period = ETERNITY + definition_period = DateUnit.ETERNITY class projected_enum_variable(Variable): value_type = Enum possible_values = enum default_value = enum.FIRST_OPTION entity = person - definition_period = ETERNITY + definition_period = DateUnit.ETERNITY def formula(person, period): return person.household("household_enum_variable", period) @@ -194,7 +197,7 @@ class household_projected_variable(Variable): possible_values = enum default_value = enum.FIRST_OPTION entity = household - definition_period = ETERNITY + definition_period = DateUnit.ETERNITY def formula(household, period): return household.value_from_first_person(household.members("person_enum_variable", period)) @@ -204,7 +207,7 @@ class person_enum_variable(Variable): possible_values = enum default_value = enum.FIRST_OPTION entity = person - definition_period = ETERNITY + definition_period = DateUnit.ETERNITY system.add_variables(household_projected_variable, person_enum_variable) @@ -275,14 +278,14 @@ class household_level_variable(Variable): possible_values = enum default_value = enum.FIRST_OPTION entity = household_entity - definition_period = ETERNITY + definition_period = DateUnit.ETERNITY class projected_family_level_variable(Variable): value_type = Enum possible_values = enum default_value = enum.FIRST_OPTION entity = family_entity - definition_period = ETERNITY + definition_period = DateUnit.ETERNITY def formula(family, period): return family.household("household_level_variable", period) @@ -290,7 +293,7 @@ def formula(family, period): class decoded_projected_family_level_variable(Variable): value_type = str entity = family_entity - definition_period = ETERNITY + definition_period = DateUnit.ETERNITY def formula(family, period): return family.household("household_level_variable", period).decode_to_str() diff --git a/tests/core/test_reforms.py b/tests/core/test_reforms.py index 8735cee18f..de2a47fc7c 100644 --- a/tests/core/test_reforms.py +++ b/tests/core/test_reforms.py @@ -2,12 +2,15 @@ import pytest -from openfisca_core import periods +from openfisca_country_template.entities import Household, Person + +from openfisca_core import holders, periods, simulations +from openfisca_core.parameters import ValuesHistory, ParameterNode +from openfisca_core.periods import DateUnit from openfisca_core.periods import Instant +from openfisca_core.reforms import Reform from openfisca_core.tools import assert_near -from openfisca_core.parameters import ValuesHistory, ParameterNode -from openfisca_country_template.entities import Household, Person -from openfisca_core.model_api import * # noqa analysis:ignore +from openfisca_core.variables import Variable class goes_to_school(Variable): @@ -15,7 +18,7 @@ class goes_to_school(Variable): default_value = True entity = Person label = "The person goes to school (only relevant for children)" - definition_period = MONTH + definition_period = DateUnit.MONTH class WithBasicIncomeNeutralized(Reform): @@ -216,7 +219,7 @@ class new_variable(Variable): value_type = int label = "Nouvelle variable introduite par la réforme" entity = Household - definition_period = MONTH + definition_period = DateUnit.MONTH def formula(household, period): return household.empty_array() + 10 @@ -240,7 +243,7 @@ class new_dated_variable(Variable): value_type = int label = "Nouvelle variable introduite par la réforme" entity = Household - definition_period = MONTH + definition_period = DateUnit.MONTH def formula_2010_01_01(household, period): return household.empty_array() + 10 @@ -263,7 +266,7 @@ def apply(self): def test_update_variable(make_simulation, tax_benefit_system): class disposable_income(Variable): - definition_period = MONTH + definition_period = DateUnit.MONTH def formula_2018(household, period): return household.empty_array() + 10 @@ -294,7 +297,7 @@ def apply(self): def test_replace_variable(tax_benefit_system): class disposable_income(Variable): - definition_period = MONTH + definition_period = DateUnit.MONTH entity = Person label = "Disposable income" value_type = float @@ -355,9 +358,9 @@ class some_variable(Variable): value_type = int entity = Person label = "Variable with many attributes" - definition_period = MONTH - set_input = set_input_divide_by_period - calculate_output = calculate_output_add + definition_period = DateUnit.MONTH + set_input = holders.set_input_divide_by_period + calculate_output = simulations.calculate_output_add tax_benefit_system.add_variable(some_variable) diff --git a/tests/core/test_simulation_builder.py b/tests/core/test_simulation_builder.py index b6a558751d..7d451dc315 100644 --- a/tests/core/test_simulation_builder.py +++ b/tests/core/test_simulation_builder.py @@ -5,9 +5,10 @@ from openfisca_country_template import entities, situation_examples -from openfisca_core import periods, tools +from openfisca_core import tools from openfisca_core.errors import SituationParsingError from openfisca_core.indexed_enums import Enum +from openfisca_core.periods import DateUnit from openfisca_core.populations import Population from openfisca_core.simulations import Simulation, SimulationBuilder from openfisca_core.tools import test_runner @@ -18,7 +19,7 @@ def int_variable(persons): class intvar(Variable): - definition_period = periods.ETERNITY + definition_period = DateUnit.ETERNITY value_type = int entity = persons @@ -32,7 +33,7 @@ def __init__(self): def date_variable(persons): class datevar(Variable): - definition_period = periods.ETERNITY + definition_period = DateUnit.ETERNITY value_type = datetime.date entity = persons @@ -46,7 +47,7 @@ def __init__(self): def enum_variable(): class TestEnum(Variable): - definition_period = periods.ETERNITY + definition_period = DateUnit.ETERNITY value_type = Enum dtype = 'O' default_value = '0' diff --git a/tests/core/tools/test_runner/test_yaml_runner.py b/tests/core/tools/test_runner/test_yaml_runner.py index bd7aaccad7..24c4f5f15f 100644 --- a/tests/core/tools/test_runner/test_yaml_runner.py +++ b/tests/core/tools/test_runner/test_yaml_runner.py @@ -9,7 +9,7 @@ from openfisca_core.variables import Variable from openfisca_core.populations import Population from openfisca_core.entities import Entity -from openfisca_core.periods import ETERNITY +from openfisca_core.periods import DateUnit class TaxBenefitSystem: @@ -73,7 +73,7 @@ def __init__(self, test): class TestVariable(Variable): - definition_period = ETERNITY + definition_period = DateUnit.ETERNITY value_type = float def __init__(self): diff --git a/tests/core/variables/test_annualize.py b/tests/core/variables/test_annualize.py index 62b0a79b14..1529676574 100644 --- a/tests/core/variables/test_annualize.py +++ b/tests/core/variables/test_annualize.py @@ -1,10 +1,11 @@ import numpy as np from pytest import fixture -from openfisca_core import periods -from openfisca_core.model_api import * # noqa analysis:ignore from openfisca_country_template.entities import Person -from openfisca_core.variables import get_annualized_variable + +from openfisca_core import periods +from openfisca_core.periods import DateUnit +from openfisca_core.variables import Variable, get_annualized_variable @fixture @@ -15,7 +16,7 @@ def monthly_variable(): class monthly_variable(Variable): value_type = int entity = Person - definition_period = MONTH + definition_period = DateUnit.MONTH def formula(person, period, parameters): variable.calculation_count += 1 @@ -47,7 +48,7 @@ def test_without_annualize(monthly_variable): yearly_sum = sum( person('monthly_variable', month) - for month in period.get_subperiods(MONTH) + for month in period.get_subperiods(DateUnit.MONTH) ) assert monthly_variable.calculation_count == 11 @@ -62,7 +63,7 @@ def test_with_annualize(monthly_variable): yearly_sum = sum( person('monthly_variable', month) - for month in period.get_subperiods(MONTH) + for month in period.get_subperiods(DateUnit.MONTH) ) assert monthly_variable.calculation_count == 0 @@ -77,7 +78,7 @@ def test_with_partial_annualize(monthly_variable): yearly_sum = sum( person('monthly_variable', month) - for month in period.get_subperiods(MONTH) + for month in period.get_subperiods(DateUnit.MONTH) ) assert monthly_variable.calculation_count == 11 diff --git a/tests/core/variables/test_variables.py b/tests/core/variables/test_variables.py index 876145bde1..a8128b970b 100644 --- a/tests/core/variables/test_variables.py +++ b/tests/core/variables/test_variables.py @@ -2,16 +2,17 @@ import datetime -from openfisca_core.model_api import Variable -from openfisca_core.periods import MONTH, ETERNITY -from openfisca_core.simulation_builder import SimulationBuilder -from openfisca_core.tools import assert_near +from pytest import fixture, raises, mark import openfisca_country_template as country_template import openfisca_country_template.situation_examples from openfisca_country_template.entities import Person -from pytest import fixture, raises, mark +from openfisca_core.periods import DateUnit +from openfisca_core.simulation_builder import SimulationBuilder +from openfisca_core.tools import assert_near +from openfisca_core.variables import Variable + # Check which date is applied whether it comes from Variable attribute (end) # or formula(s) dates. @@ -58,7 +59,7 @@ def get_message(error): class variable__no_date(Variable): value_type = int entity = Person - definition_period = MONTH + definition_period = DateUnit.MONTH label = "Variable without date." @@ -78,7 +79,7 @@ def test_variable__no_date(): class variable__strange_end_attribute(Variable): value_type = int entity = Person - definition_period = MONTH + definition_period = DateUnit.MONTH label = "Variable with dubious end attribute, no formula." end = '1989-00-00' @@ -100,7 +101,7 @@ def test_variable__strange_end_attribute(): class variable__end_attribute(Variable): value_type = int entity = Person - definition_period = MONTH + definition_period = DateUnit.MONTH label = "Variable with end attribute, no formula." end = '1989-12-31' @@ -127,7 +128,7 @@ def test_variable__end_attribute_set_input(simulation): class end_attribute__one_simple_formula(Variable): value_type = int entity = Person - definition_period = MONTH + definition_period = DateUnit.MONTH label = "Variable with end attribute, one formula without date." end = '1989-12-31' @@ -170,7 +171,7 @@ def test_dates__end_attribute__one_simple_formula(): class no_end_attribute__one_formula__strange_name(Variable): value_type = int entity = Person - definition_period = MONTH + definition_period = DateUnit.MONTH label = "Variable without end attribute, one stangely named formula." def formula_2015_toto(individu, period): @@ -187,7 +188,7 @@ def test_add__no_end_attribute__one_formula__strange_name(): class no_end_attribute__one_formula__start(Variable): value_type = int entity = Person - definition_period = MONTH + definition_period = DateUnit.MONTH label = "Variable without end attribute, one dated formula." def formula_2000_01_01(individu, period): @@ -219,7 +220,7 @@ def test_dates__no_end_attribute__one_formula__start(): class no_end_attribute__one_formula__eternity(Variable): value_type = int entity = Person - definition_period = ETERNITY # For this entity, this variable shouldn't evolve through time + definition_period = DateUnit.ETERNITY # For this entity, this variable shouldn't evolve through time label = "Variable without end attribute, one dated formula." def formula_2000_01_01(individu, period): @@ -255,7 +256,7 @@ def test_call__no_end_attribute__one_formula__eternity_after(simulation): class no_end_attribute__formulas__start_formats(Variable): value_type = int entity = Person - definition_period = MONTH + definition_period = DateUnit.MONTH label = "Variable without end attribute, multiple dated formulas." def formula_2000(individu, period): @@ -307,7 +308,7 @@ def test_call__no_end_attribute__formulas__start_formats(simulation): class no_attribute__formulas__different_names__dates_overlap(Variable): value_type = int entity = Person - definition_period = MONTH + definition_period = DateUnit.MONTH label = "Variable, no end attribute, multiple dated formulas with different names but same dates." def formula_2000(individu, period): @@ -327,7 +328,7 @@ def test_add__no_attribute__formulas__different_names__dates_overlap(): class no_attribute__formulas__different_names__no_overlap(Variable): value_type = int entity = Person - definition_period = MONTH + definition_period = DateUnit.MONTH label = "Variable, no end attribute, multiple dated formulas with different names and no date overlap." def formula_2000_01_01(individu, period): @@ -356,7 +357,7 @@ def test_call__no_attribute__formulas__different_names__no_overlap(simulation): class end_attribute__one_formula__start(Variable): value_type = int entity = Person - definition_period = MONTH + definition_period = DateUnit.MONTH label = "Variable with end attribute, one dated formula." end = '2001-12-31' @@ -383,7 +384,7 @@ def test_call__end_attribute__one_formula__start(simulation): class stop_attribute_before__one_formula__start(Variable): value_type = int entity = Person - definition_period = MONTH + definition_period = DateUnit.MONTH label = "Variable with stop attribute only coming before formula start." end = '1990-01-01' @@ -400,7 +401,7 @@ def test_add__stop_attribute_before__one_formula__start(): class end_attribute_restrictive__one_formula(Variable): value_type = int entity = Person - definition_period = MONTH + definition_period = DateUnit.MONTH label = "Variable with end attribute, one dated formula and dates intervals overlap." end = '2001-01-01' @@ -427,7 +428,7 @@ def test_call__end_attribute_restrictive__one_formula(simulation): class end_attribute__formulas__different_names(Variable): value_type = int entity = Person - definition_period = MONTH + definition_period = DateUnit.MONTH label = "Variable with end attribute, multiple dated formulas with different names." end = '2010-12-31' @@ -468,7 +469,7 @@ def test_unexpected_attr(): class variable_with_strange_attr(Variable): value_type = int entity = Person - definition_period = MONTH + definition_period = DateUnit.MONTH unexpected = '???' with raises(ValueError): diff --git a/tests/fixtures/appclient.py b/tests/fixtures/appclient.py index a140e0f938..1810488d5f 100644 --- a/tests/fixtures/appclient.py +++ b/tests/fixtures/appclient.py @@ -20,7 +20,7 @@ def test_client(tax_benefit_system): class new_variable(Variable): value_type = float entity = entities.Person - definition_period = periods.MONTH + definition_period = DateUnit.MONTH label = "New variable" reference = "https://law.gov.example/new_variable" # Always use the most official source diff --git a/tests/fixtures/variables.py b/tests/fixtures/variables.py index cd0d9b70ce..aab7cda58d 100644 --- a/tests/fixtures/variables.py +++ b/tests/fixtures/variables.py @@ -1,9 +1,9 @@ -from openfisca_core import periods +from openfisca_core.periods import DateUnit from openfisca_core.variables import Variable class TestVariable(Variable): - definition_period = periods.ETERNITY + definition_period = DateUnit.ETERNITY value_type = float def __init__(self, entity):