Skip to content

Commit

Permalink
Keep numbers for runtime type checks, use float for type hints
Browse files Browse the repository at this point in the history
  • Loading branch information
robsdedude committed May 6, 2024
1 parent 023c7a3 commit aecc78a
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 10 deletions.
18 changes: 11 additions & 7 deletions freezegun/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -510,9 +510,10 @@ def __call__(self) -> datetime.datetime:
return self.time_to_freeze + (real_datetime.now() - self.start)

def tick(self, delta: Union[datetime.timedelta, float]=datetime.timedelta(seconds=1)) -> datetime.datetime:
if isinstance(delta, numbers.Real):
# noinspection PyTypeChecker
self.move_to(self.time_to_freeze + datetime.timedelta(seconds=delta))
if isinstance(delta, numbers.Integral):
self.move_to(self.time_to_freeze + datetime.timedelta(seconds=int(delta)))
elif isinstance(delta, numbers.Real):
self.move_to(self.time_to_freeze + datetime.timedelta(seconds=float(delta)))
else:
self.move_to(self.time_to_freeze + delta) # type: ignore
return self.time_to_freeze
Expand All @@ -532,9 +533,10 @@ def __call__(self) -> datetime.datetime:
return self.time_to_freeze

def tick(self, delta: Union[datetime.timedelta, float]=datetime.timedelta(seconds=1)) -> datetime.datetime:
if isinstance(delta, numbers.Real):
# noinspection PyTypeChecker
self.time_to_freeze += datetime.timedelta(seconds=delta)
if isinstance(delta, numbers.Integral):
self.move_to(self.time_to_freeze + datetime.timedelta(seconds=int(delta)))
elif isinstance(delta, numbers.Real):
self.move_to(self.time_to_freeze + datetime.timedelta(seconds=float(delta)))
else:
self.time_to_freeze += delta # type: ignore
return self.time_to_freeze
Expand All @@ -560,8 +562,10 @@ def __call__(self) -> datetime.datetime:
def tick(self, delta: Union[datetime.timedelta, float, None]=None) -> datetime.datetime:
if not delta:
delta = datetime.timedelta(seconds=self.step_width)
elif isinstance(delta, numbers.Integral):
delta = datetime.timedelta(seconds=int(delta))
elif isinstance(delta, numbers.Real):
delta = datetime.timedelta(seconds=delta)
delta = datetime.timedelta(seconds=float(delta))
self.time_to_freeze += delta # type: ignore
return self.time_to_freeze

Expand Down
12 changes: 12 additions & 0 deletions tests/test_datetimes.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import time
import calendar
import datetime
import fractions
import unittest
import locale
import sys
Expand Down Expand Up @@ -180,6 +181,17 @@ def test_manual_increment() -> None:
assert frozen_datetime.tick(delta=datetime.timedelta(seconds=10)) == expected
assert frozen_datetime() == expected

expected = initial_datetime + datetime.timedelta(seconds=22.5)
ticked_time = frozen_datetime.tick(
delta=fractions.Fraction(3, 2) # type: ignore
# type hints follow the recommendation of
# https://peps.python.org/pep-0484/#the-numeric-tower
# which means for instance `Fraction`s work at runtime, but not
# during static type analysis
)
assert ticked_time == expected
assert frozen_datetime() == expected


def test_move_to() -> None:
initial_datetime = datetime.datetime(year=1, month=7, day=12,
Expand Down
17 changes: 14 additions & 3 deletions tests/test_operations.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import datetime
import fractions
import pytest
from freezegun import freeze_time
from dateutil.relativedelta import relativedelta
from datetime import timedelta, tzinfo
from tests import utils
from typing import Any
from typing import Any, Union


@freeze_time("2012-01-14")
Expand Down Expand Up @@ -109,10 +110,20 @@ def test_auto_tick() -> None:
(
(datetime.timedelta(milliseconds=1500), 1.5),
(1, 1),
(1.5, 1.5)
(1.5, 1.5),
(fractions.Fraction(3, 2), 1.5),
)
)
def test_auto_and_manual_tick(tick, expected_diff) -> None:
def test_auto_and_manual_tick(
tick: Union[
datetime.timedelta,
float,
# fractions.Fraction,
# Fraction works at runtime, but not at type-checking time
# cf. https://peps.python.org/pep-0484/#the-numeric-tower
],
expected_diff: float
) -> None:
first_time = datetime.datetime(2020, 1, 14, 0, 0, 0, 1)

with freeze_time(first_time, auto_tick_seconds=2) as frozen_time:
Expand Down

0 comments on commit aecc78a

Please sign in to comment.