Skip to content

Commit

Permalink
Merge pull request #546 from robsdedude/patch-1
Browse files Browse the repository at this point in the history
Fix `tick` delta type handling
  • Loading branch information
bblommers committed May 8, 2024
2 parents 17ea422 + df263dc commit ea054a3
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 10 deletions.
24 changes: 15 additions & 9 deletions freezegun/api.py
Expand Up @@ -509,10 +509,11 @@ def __init__(self, time_to_freeze: datetime.datetime, start: datetime.datetime):
def __call__(self) -> datetime.datetime:
return self.time_to_freeze + (real_datetime.now() - self.start)

def tick(self, delta: Union[datetime.timedelta, int]=datetime.timedelta(seconds=1)) -> datetime.datetime:
if isinstance(delta, numbers.Real):
# noinspection PyTypeChecker
self.move_to(self.time_to_freeze + datetime.timedelta(seconds=delta))
def tick(self, delta: Union[datetime.timedelta, float]=datetime.timedelta(seconds=1)) -> datetime.datetime:
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 @@ -531,10 +532,11 @@ def __init__(self, time_to_freeze: datetime.datetime):
def __call__(self) -> datetime.datetime:
return self.time_to_freeze

def tick(self, delta: Union[datetime.timedelta, int]=datetime.timedelta(seconds=1)) -> datetime.datetime:
if isinstance(delta, numbers.Real):
# noinspection PyTypeChecker
self.time_to_freeze += datetime.timedelta(seconds=delta)
def tick(self, delta: Union[datetime.timedelta, float]=datetime.timedelta(seconds=1)) -> datetime.datetime:
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 @@ -557,9 +559,13 @@ def __call__(self) -> datetime.datetime:
self.tick()
return return_time

def tick(self, delta: Union[datetime.timedelta, int, None]=None) -> 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=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
@@ -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
39 changes: 38 additions & 1 deletion tests/test_operations.py
@@ -1,9 +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 @@ -102,3 +104,38 @@ def test_auto_tick() -> None:
auto_incremented_time = datetime.datetime.now()
assert first_time + datetime.timedelta(seconds=15) == auto_incremented_time


@pytest.mark.parametrize(
"tick,expected_diff",
(
(datetime.timedelta(milliseconds=1500), 1.5),
(1, 1),
(1.5, 1.5),
(fractions.Fraction(3, 2), 1.5),
)
)
def test_auto_and_manual_tick(
tick: Union[
datetime.timedelta,
int,
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:
frozen_time.tick(tick)
incremented_time = datetime.datetime.now()
expected_time = first_time + datetime.timedelta(seconds=expected_diff)
assert incremented_time == expected_time

expected_time += datetime.timedelta(seconds=2) # auto_tick_seconds

frozen_time.tick(tick)
incremented_time = datetime.datetime.now()
expected_time += datetime.timedelta(seconds=expected_diff)
assert incremented_time == expected_time

0 comments on commit ea054a3

Please sign in to comment.