diff --git a/CHANGELOG.rst b/CHANGELOG.rst index d83e48d..5984577 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,6 +2,10 @@ Changelog ========= +* Fix segmentation fault when the first ``travel()`` call in a process uses a ``timedelta``. + + Thanks to Marcin Sulikowski for the report in `Issue #431 `__. + 2.14.0 (2024-03-03) ------------------- diff --git a/src/time_machine/__init__.py b/src/time_machine/__init__.py index 877b325..2553b3d 100644 --- a/src/time_machine/__init__.py +++ b/src/time_machine/__init__.py @@ -5,6 +5,7 @@ import inspect import os import sys +import time as time_module import uuid from collections.abc import Generator from time import gmtime as orig_gmtime @@ -126,7 +127,7 @@ def extract_timestamp_tzname( dest = dest.replace(tzinfo=dt.timezone.utc) timestamp = dest.timestamp() elif isinstance(dest, dt.timedelta): - timestamp = time() + dest.total_seconds() + timestamp = time_module.time() + dest.total_seconds() elif isinstance(dest, dt.date): timestamp = dt.datetime.combine( dest, dt.time(0, 0), tzinfo=dt.timezone.utc diff --git a/tests/test_time_machine.py b/tests/test_time_machine.py index 11dc433..5557148 100644 --- a/tests/test_time_machine.py +++ b/tests/test_time_machine.py @@ -3,6 +3,7 @@ import asyncio import datetime as dt import os +import subprocess import sys import time import typing @@ -10,6 +11,7 @@ from contextlib import contextmanager from importlib.util import module_from_spec from importlib.util import spec_from_file_location +from textwrap import dedent from unittest import SkipTest from unittest import TestCase from unittest import mock @@ -472,6 +474,25 @@ def test_destination_timedelta(): assert now + 3600 <= time.time() <= now + 3601 +def test_destination_timedelta_first_travel_in_process(): + # Would previously segfault + subprocess.run( + [ + sys.executable, + "-c", + dedent( + """ + from datetime import timedelta + import time_machine + with time_machine.travel(timedelta()): + pass + """ + ), + ], + check=True, + ) + + def test_destination_timedelta_negative(): now = time.time() with time_machine.travel(dt.timedelta(seconds=-3600)):