Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/time_machine/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,8 @@ def move_to(
self._tick = tick

def _start(self) -> None:
# Reset UUID7 module's last timestamp cache
uuid._last_timestamp_v7 = None # type: ignore[attr-defined]
if HAVE_TZSET and self._destination_tzname is not None:
self._orig_tz = os.environ.get("TZ")
os.environ["TZ"] = self._destination_tzname
Expand Down
53 changes: 53 additions & 0 deletions tests/test_time_machine.py
Original file line number Diff line number Diff line change
Expand Up @@ -905,6 +905,10 @@ def time_from_uuid1(value: uuid.UUID) -> dt.datetime:
return dt.datetime(1582, 10, 15) + dt.timedelta(microseconds=value.time // 10)


def time_from_uuid7(value: uuid.UUID) -> dt.datetime:
return dt.datetime.fromtimestamp(value.time / 1000)


def test_uuid1():
"""
Test that the uuid.uuid1() methods generate values for the destination.
Expand All @@ -917,6 +921,38 @@ def test_uuid1():
assert time_from_uuid1(uuid.uuid1()) == destination


@pytest.mark.skipif(
sys.version_info < (3, 14),
reason="Only valid on Python 3.14+",
)
def test_uuid7() -> None:
"""
Test that we can go back in time after setting a future date.
Normally UUID7 would disallow this, since it keeps track of
the _last_timestamp_v7, but we override that now.
"""
if not hasattr(uuid, "uuid7"):
pytest.skip("uuid.uuid7 is not available")
Comment on lines +934 to +935
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only to make mypy happy. What is prefered here?
@pytest.mark.skipif(...) or internal check?


destination_future = dt.datetime(2056, 2, 6, 14, 3, 21)
destination_present = dt.datetime(2025, 1, 1)
destination_past = dt.datetime(1978, 7, 6, 23, 6, 31)

with time_machine.travel(destination_future, tick=False):
assert time_from_uuid7(uuid.uuid7()) == destination_future

with time_machine.travel(destination_past, tick=False):
assert time_from_uuid7(uuid.uuid7()) == destination_past

# Verify stack does not interfere
with time_machine.travel(destination_present, tick=False):
with time_machine.travel(destination_future, tick=False):
assert time_from_uuid7(uuid.uuid7()) == destination_future

with time_machine.travel(destination_past, tick=False):
assert time_from_uuid7(uuid.uuid7()) == destination_past


# error handling tests


Expand Down Expand Up @@ -1233,6 +1269,23 @@ def test_fixture_shift_without_move_to(time_machine):
)


@pytest.mark.skipif(
sys.version_info < (3, 14),
reason="Only valid on Python 3.14+",
)
def test_uuid7_fixture(time_machine):
if not hasattr(uuid, "uuid7"):
pytest.skip("uuid.uuid7 is not available")

destination_future = dt.datetime(2056, 2, 6, 14, 3, 21)
time_machine.move_to(destination_future, tick=False)
assert time_from_uuid7(uuid.uuid7()) == destination_future

destination_past = dt.datetime(1978, 7, 6, 23, 6, 31)
time_machine.move_to(destination_past, tick=False)
assert time_from_uuid7(uuid.uuid7()) == destination_past


def test_marker_function(testdir):
testdir.makepyfile(
"""
Expand Down