Skip to content

Commit 1b79d3c

Browse files
committed
Fix typing
1 parent 9a96aed commit 1b79d3c

7 files changed

Lines changed: 79 additions & 71 deletions

File tree

openfisca_core/periods/_config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@
66

77
# Matches "2015", "2015-01", "2015-01-01"
88
# Does not match "2015-13", "2015-12-32"
9-
INSTANT_PATTERN: Pattern = re.compile(r"^\d{4}(-(0[1-9]|1[012]))?(-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01]))?$")
9+
INSTANT_PATTERN: Pattern[str] = re.compile(r"^\d{4}(-(0[1-9]|1[012]))?(-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01]))?$")

openfisca_core/periods/_funcs.py

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -59,28 +59,25 @@ def build_instant(value: Any) -> Optional[types.Instant]:
5959
if isinstance(value, Instant):
6060
return value
6161

62-
if isinstance(value, str):
63-
if not INSTANT_PATTERN.match(value):
64-
raise InstantFormatError(value)
62+
if isinstance(value, Period):
63+
return value.start
6564

66-
instant = Instant(
67-
int(fragment)
68-
for fragment in value.split('-', 2)[:3]
69-
)
65+
if isinstance(value, str) and not INSTANT_PATTERN.match(value):
66+
raise InstantFormatError(value)
67+
68+
if isinstance(value, str):
69+
instant = tuple(int(fragment) for fragment in value.split('-', 2)[:3])
7070

7171
elif isinstance(value, datetime.date):
72-
instant = Instant((value.year, value.month, value.day))
72+
instant = value.year, value.month, value.day
7373

7474
elif isinstance(value, int):
75-
instant = (value,)
75+
instant = value,
7676

7777
elif isinstance(value, list):
7878
assert 1 <= len(value) <= 3
7979
instant = tuple(value)
8080

81-
elif isinstance(value, Period):
82-
instant = value.start
83-
8481
else:
8582
assert isinstance(value, tuple), value
8683
assert 1 <= len(value) <= 3
@@ -226,7 +223,7 @@ def key_period_size(period: types.Period) -> str:
226223
227224
"""
228225

229-
unit, start, size = period
226+
unit, _start, size = period
230227

231228
return f"{UNIT_WEIGHTS[unit]}_{size}"
232229

openfisca_core/periods/instant_.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,11 @@
55
import calendar
66
import datetime
77

8-
from openfisca_core import types
9-
108
from ._errors import DateUnitValueError, InstantTypeError, OffsetTypeError
119
from ._units import DAY, MONTH, YEAR
1210

1311

14-
class Instant(tuple):
12+
class Instant(tuple[int, int, int]):
1513
"""An instant in time (``year``, ``month``, ``day``).
1614
1715
An ``Instant`` represents the most atomic and indivisible
@@ -85,7 +83,7 @@ def __str__(self) -> str:
8583
return str(self)
8684

8785
@staticmethod
88-
def to_date(value: Optional[types.Instant]) -> Optional[datetime.date]:
86+
def to_date(value: Optional[Instant]) -> Optional[datetime.date]:
8987
"""Returns the date representation of an ``Instant``.
9088
9189
Args:
@@ -108,7 +106,7 @@ def to_date(value: Optional[types.Instant]) -> Optional[datetime.date]:
108106
if value is None:
109107
return None
110108

111-
if isinstance(value, types.Instant):
109+
if isinstance(value, Instant):
112110
return value.date
113111

114112
raise InstantTypeError(value)
@@ -184,7 +182,7 @@ def date(self) -> datetime.date:
184182

185183
return self.date
186184

187-
def offset(self, offset: Union[str, int], unit: str) -> types.Instant:
185+
def offset(self, offset: Union[str, int], unit: str) -> Instant:
188186
"""Increments/decrements the given instant with offset units.
189187
190188
Args:

openfisca_core/periods/period_.py

Lines changed: 42 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,12 @@
55
import calendar
66
import datetime
77

8-
from openfisca_core import types
9-
8+
from ._errors import DateUnitValueError
109
from ._units import DAY, MONTH, YEAR, ETERNITY, UNIT_WEIGHTS
1110
from .instant_ import Instant
1211

1312

14-
class Period(tuple):
13+
class Period(tuple[str, Instant, int]):
1514
"""Toolbox to handle date intervals.
1615
1716
A ``Period`` is a triple (``unit``, ``start``, ``size``).
@@ -121,28 +120,28 @@ def __str__(self) -> str:
121120
year, month, day = start_instant
122121

123122
# 1 year long period
124-
if (unit == MONTH and size == 12 or unit == YEAR and size == 1):
123+
if unit == MONTH and size == 12 or unit == YEAR and size == 1:
125124
if month == 1:
126125
# civil year starting from january
127126
return str(year)
128127
else:
129128
# rolling year
130-
return '{}:{}-{:02d}'.format(YEAR, year, month)
129+
return f'{YEAR}:{year}-{month:02d}'
131130
# simple month
132131
if unit == MONTH and size == 1:
133-
return '{}-{:02d}'.format(year, month)
132+
return f'{year}-{month:02d}'
134133
# several civil years
135134
if unit == YEAR and month == 1:
136-
return '{}:{}:{}'.format(unit, year, size)
135+
return f'{unit}:{year}:{size}'
137136

138137
if unit == DAY:
139138
if size == 1:
140-
return '{}-{:02d}-{:02d}'.format(year, month, day)
139+
return f'{year}-{month:02d}-{day:02d}'
141140
else:
142-
return '{}:{}-{:02d}-{:02d}:{}'.format(unit, year, month, day, size)
141+
return f'{unit}:{year}-{month:02d}-{day:02d}:{size}'
143142

144143
# complex period
145-
return '{}:{}-{:02d}:{}'.format(unit, year, month, size)
144+
return f'{unit}:{year}-{month:02d}:{size}'
146145

147146
def __contains__(self, other: object) -> bool:
148147
"""Checks if a ``period`` contains another one.
@@ -162,7 +161,7 @@ def __contains__(self, other: object) -> bool:
162161
163162
"""
164163

165-
if isinstance(other, types.Period):
164+
if isinstance(other, Period):
166165
return self.start <= other.start and self.stop >= other.stop
167166

168167
return super().__contains__(other)
@@ -273,10 +272,10 @@ def size_in_months(self) -> int:
273272
274273
"""
275274

276-
if (self[0] == MONTH):
275+
if self[0] == MONTH:
277276
return self[2]
278277

279-
if(self[0] == YEAR):
278+
if self[0] == YEAR:
280279
return self[2] * 12
281280

282281
raise ValueError(f"Cannot calculate number of months in {self[0]}.")
@@ -315,7 +314,7 @@ def size_in_days(self) -> int:
315314
raise ValueError(f"Cannot calculate number of days in {unit}")
316315

317316
@property
318-
def start(self) -> types.Instant:
317+
def start(self) -> Instant:
319318
"""The ``Instant`` at which the ``Period`` starts.
320319
321320
Returns:
@@ -332,7 +331,7 @@ def start(self) -> types.Instant:
332331
return self[1]
333332

334333
@property
335-
def stop(self) -> types.Instant:
334+
def stop(self) -> Instant:
336335
"""Last day of the ``Period`` as an ``Instant``.
337336
338337
Returns:
@@ -354,7 +353,7 @@ def stop(self) -> types.Instant:
354353
year, month, day = start_instant
355354

356355
if unit == ETERNITY:
357-
return Instant((float("inf"), float("inf"), float("inf")))
356+
return Instant((1, 1, 1))
358357

359358
if unit == 'day':
360359
if size > 1:
@@ -375,7 +374,7 @@ def stop(self) -> types.Instant:
375374
year += 1
376375
month -= 12
377376
else:
378-
assert unit == 'year', 'Invalid unit: {} of type {}'.format(unit, type(unit))
377+
assert unit == 'year', f'Invalid unit: {unit} of type {type(unit)}'
379378
year += size
380379
day -= 1
381380
if day < 1:
@@ -396,7 +395,7 @@ def stop(self) -> types.Instant:
396395
return Instant((year, month, day))
397396

398397
@property
399-
def last_month(self) -> types.Period:
398+
def last_month(self) -> Period:
400399
"""Last month of the ``Period``.
401400
402401
Returns:
@@ -407,79 +406,80 @@ def last_month(self) -> types.Period:
407406
return self.first_month.offset(-1)
408407

409408
@property
410-
def last_3_months(self) -> types.Period:
409+
def last_3_months(self) -> Period:
411410
"""Last 3 months of the ``Period``.
412411
413412
Returns:
414413
A Period.
415414
416415
"""
417416

418-
start: types.Instant = self.first_month.start
419-
return self.__class__((MONTH, start, 3)).offset(-3)
417+
start: Instant = self.first_month.start
418+
return Period((MONTH, start, 3)).offset(-3)
420419

421420
@property
422-
def last_year(self) -> types.Period:
421+
def last_year(self) -> Period:
423422
"""Last year of the ``Period``."""
424-
start: types.Instant = self.start.offset("first-of", YEAR)
425-
return self.__class__((YEAR, start, 1)).offset(-1)
423+
start: Instant = self.start.offset("first-of", YEAR)
424+
return Period((YEAR, start, 1)).offset(-1)
426425

427426
@property
428-
def n_2(self) -> types.Period:
427+
def n_2(self) -> Period:
429428
"""Last 2 years of the ``Period``.
430429
431430
Returns:
432431
A Period.
433432
434433
"""
435434

436-
start: types.Instant = self.start.offset("first-of", YEAR)
437-
return self.__class__((YEAR, start, 1)).offset(-2)
435+
start: Instant = self.start.offset("first-of", YEAR)
436+
return Period((YEAR, start, 1)).offset(-2)
438437

439438
@property
440-
def this_year(self) -> types.Period:
439+
def this_year(self) -> Period:
441440
"""A new year ``Period`` starting at the beginning of the year.
442441
443442
Returns:
444443
A Period.
445444
446445
"""
447446

448-
start: types.Instant = self.start.offset("first-of", YEAR)
449-
return self.__class__((YEAR, start, 1))
447+
start: Instant = self.start.offset("first-of", YEAR)
448+
return Period((YEAR, start, 1))
450449

451450
@property
452-
def first_month(self) -> types.Period:
451+
def first_month(self) -> Period:
453452
"""A new month ``Period`` starting at the first of the month.
454453
455454
Returns:
456455
A Period.
457456
458457
"""
459458

460-
start: types.Instant = self.start.offset("first-of", MONTH)
461-
return self.__class__((MONTH, start, 1))
459+
start: Instant = self.start.offset("first-of", MONTH)
460+
return Period((MONTH, start, 1))
462461

463462
@property
464-
def first_day(self) -> types.Period:
463+
def first_day(self) -> Period:
465464
"""A new day ``Period``.
466465
467466
Returns:
468467
A Period.
469468
470469
"""
471-
return self.__class__((DAY, self.start, 1))
470+
return Period((DAY, self.start, 1))
472471

473-
def get_subperiods(self, unit: str) -> Sequence[types.Period]:
472+
def get_subperiods(self, unit: str) -> Sequence[Period]:
474473
"""Return the list of all the periods of unit ``unit``.
475474
476475
Args:
477476
unit: A string representing period's ``unit``.
478477
479478
Returns:
480-
A list of Periods.
479+
A list of periods.
481480
482481
Raises:
482+
DateUnitValueError: If the ``unit`` is not a valid date unit.
483483
ValueError: If the period's unit is smaller than the given unit.
484484
485485
Examples:
@@ -494,7 +494,7 @@ def get_subperiods(self, unit: str) -> Sequence[types.Period]:
494494
"""
495495

496496
if UNIT_WEIGHTS[self.unit] < UNIT_WEIGHTS[unit]:
497-
raise ValueError('Cannot subdivide {0} into {1}'.format(self.unit, unit))
497+
raise ValueError(f"Cannot subdivide {self.unit} into {unit}")
498498

499499
if unit == YEAR:
500500
return [self.this_year.offset(i, YEAR) for i in range(self.size)]
@@ -505,11 +505,13 @@ def get_subperiods(self, unit: str) -> Sequence[types.Period]:
505505
if unit == DAY:
506506
return [self.first_day.offset(i, DAY) for i in range(self.size_in_days)]
507507

508+
raise DateUnitValueError(unit)
509+
508510
def offset(
509511
self,
510512
offset: Union[str, int],
511513
unit: Optional[str] = None,
512-
) -> types.Period:
514+
) -> Period:
513515
"""Increment (or decrement) the given period with offset units.
514516
515517
Args:
@@ -534,4 +536,4 @@ def offset(
534536
535537
"""
536538

537-
return self.__class__((self[0], self[1].offset(offset, self[0] if unit is None else unit), self[2]))
539+
return Period((self[0], self[1].offset(offset, self[0] if unit is None else unit), self[2]))

openfisca_core/taxbenefitsystems/tax_benefit_system.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,13 @@
1414
import traceback
1515
import typing
1616

17-
from openfisca_core import commons, periods, variables
17+
from openfisca_core import commons, periods, types, variables
1818
from openfisca_core.entities import Entity
1919
from openfisca_core.errors import VariableNameConflictError, VariableNotFoundError
2020
from openfisca_core.parameters import ParameterNode
2121
from openfisca_core.periods import Instant, Period
2222
from openfisca_core.populations import Population, GroupPopulation
2323
from openfisca_core.simulations import SimulationBuilder
24-
from openfisca_core.types import ParameterNodeAtInstant
2524
from openfisca_core.variables import Variable
2625

2726
log = logging.getLogger(__name__)
@@ -43,7 +42,7 @@ class TaxBenefitSystem:
4342
person_entity: Entity
4443

4544
_base_tax_benefit_system = None
46-
_parameters_at_instant_cache: Dict[Instant, ParameterNodeAtInstant] = {}
45+
_parameters_at_instant_cache: Dict[Instant, types.ParameterNodeAtInstant] = {}
4746
person_key_plural = None
4847
preprocess_parameters = None
4948
baseline = None # Baseline tax-benefit system. Used only by reforms. Note: Reforms can be chained.
@@ -385,8 +384,8 @@ def _get_baseline_parameters_at_instant(self, instant):
385384
@functools.lru_cache()
386385
def get_parameters_at_instant(
387386
self,
388-
instant: Union[str, int, Period, Instant],
389-
) -> Optional[ParameterNodeAtInstant]:
387+
instant: Union[str, int, types.Period, types.Instant],
388+
) -> Optional[types.ParameterNodeAtInstant]:
390389
"""Get the parameters of the legislation at a given instant
391390
392391
Args:
@@ -397,7 +396,7 @@ def get_parameters_at_instant(
397396
398397
"""
399398

400-
key: Instant
399+
key: Optional[types.Instant]
401400
msg: str
402401

403402
if isinstance(instant, Instant):
@@ -410,7 +409,7 @@ def get_parameters_at_instant(
410409
key = periods.build_instant(instant)
411410

412411
else:
413-
msg = f"Expected an Instant (e.g. Instant((2017, 1, 1)) ). Got: {key}."
412+
msg = f"Expected an Instant (e.g. Instant((2017, 1, 1)) ). Got: {instant}."
414413
raise AssertionError(msg)
415414

416415
if self.parameters is None:

0 commit comments

Comments
 (0)