Registry / testing / freezegun

freezegun

JSON →
library1.5.5pypypi✓ verified 49d ago

freezegun is a Python library (currently at version 1.5.5) that enables your tests to 'travel through time' by mocking the `datetime`, `date`, `time`, and `pendulum` modules. It simplifies testing time-sensitive code by allowing developers to freeze the current time or simulate its passage, ensuring deterministic and reliable test execution. The project maintains a regular release cadence, with frequent patch and minor updates.

testing
pip install freezegun
Install & Compatibility
Where this runs
tested against v1.5.5 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.925 runs
installs and imports cleanly · install 0.0s · import 0.378s · 18.8MB
glibc
py 3.103.925 runs
installs and imports cleanly · install 1.7s · import 0.325s · 19MB
17MB installed
● package 17MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

freeze_time
from freezegun import freeze_time

The most common way to use freezegun is via the `@freeze_time` decorator for test functions or the `with freeze_time(...)` context manager for specific blocks of code. You can pass a string representing the desired date and time. The `tick=True` parameter allows time to advance naturally (or manually with `frozen_datetime.tick()`) after the initial freeze, useful for testing time-sensitive sequences or durations. It effectively mocks `datetime.datetime.now()`, `datetime.date.today()`, `time.time()`, and related functions.

import datetime from freezegun import freeze_time @freeze_time("2023-10-26 14:30:00") def test_fixed_time_decorator(): assert datetime.datetime.now() == datetime.datetime(2023, 10, 26, 14, 30, 0) assert datetime.date.today() == datetime.date(2023, 10, 26) def test_fixed_time_context_manager(): with freeze_time("2024-01-01 00:00:00"): assert datetime.datetime.now() == datetime.datetime(2024, 1, 1, 0, 0, 0) assert datetime.datetime.utcnow() == datetime.datetime(2024, 1, 1, 0, 0, 0) def test_advancing_time(): with freeze_time("2023-01-01 10:00:00", tick=True) as frozen_datetime: start_time = datetime.datetime.now() print(f"Start: {start_time}") # Simulate some operations that take time, like an external API call # In real tests, you might have code here that calls `datetime.now()` multiple times frozen_datetime.tick(delta=datetime.timedelta(seconds=5)) after_tick = datetime.datetime.now() print(f"After tick: {after_tick}") assert after_tick - start_time == datetime.timedelta(seconds=5) test_fixed_time_decorator() test_fixed_time_context_manager() test_advancing_time()
Debug
Known issues
gotchaPerformance overhead in large projects: freezegun works by scanning and patching all imported modules that use date/time functions. In applications with many modules or complex dependency trees, this 'find-and-replace' mechanism can introduce significant overhead, making tests noticeably slower. For performance-critical scenarios, libraries like `time-machine` which mock at the C layer may be faster.
fix
For smaller projects, this overhead is usually negligible. For large projects with slow time-mocking tests, consider profiling to confirm `freezegun` as the bottleneck and evaluate alternatives like `time-machine`. Ensure `freezegun` is only active for the specific tests requiring time manipulation.
affects: All versions
breakingAsyncio compatibility issues: Prior to version 1.4.0, using `freezegun` with `asyncio` could cause `asyncio.sleep()` and other monotonic time-dependent functions to hang indefinitely, as `time.monotonic()` was also frozen. This was a common pitfall for asynchronous applications.
fix
Upgrade to freezegun 1.4.0 or newer. Use the `real_asyncio=True` parameter with `freeze_time` (e.g., `with freeze_time('2023-01-01', real_asyncio=True):`) to allow asyncio event loops to use real monotonic time while other time functions remain frozen.
affects: <1.4.0
gotchaIncomplete mocking scope: freezegun primarily patches module-level imports of `datetime` and `time` functions. It may not intercept calls to time functions that are 'hidden' inside arbitrary objects, set as default function arguments during module import, or invoked directly from C extensions (e.g., Cython-compiled code or certain low-level system calls made by third-party libraries).
fix
Be aware of how time-related functions are imported and used in the code under test. If you encounter unmocked time, inspect the import path and call stack. For C extensions or deeply embedded time calls, `freezegun` might not be sufficient, and you might need to use other mocking strategies or a library that intercepts at a lower level (like `time-machine`).
affects: All versions
gotchaTimezone inconsistencies: Freezing time without explicitly managing timezones can lead to unexpected discrepancies, particularly when mixing `datetime.now()` (timezone-aware/local) and `datetime.utcnow()` (naive UTC) or `time.time()`. Issues can arise around Daylight Saving Time (DST) transitions if not handled carefully.
fix
Always specify the desired timezone when freezing time if your application is timezone-aware (e.g., `freeze_time('2023-10-26 14:30:00', tz_offset=-5)` or ensuring `datetime.now()` is explicitly timezone-aware where needed). Test edge cases like DST transitions to ensure consistent behavior.
affects: All versions
gotchaExternal network call issues (SSL/Certificates): Freezing time to a date far in the past can cause `SSLCertVerificationError` when making external HTTP requests. This happens because the SSL certificates used by servers have validity periods, and if the frozen time falls outside this period (e.g., before the certificate's 'notBefore' date), the certificate validation will fail.
fix
When testing code that makes external HTTP requests with SSL, ensure the frozen time is within the validity period of common SSL certificates. Alternatively, if appropriate for your test, consider mocking the external HTTP calls entirely or disabling SSL verification for that specific test (with caution).
affects: All versions
gotcha`freezegun`'s `tick()` or `travel()` functions may introduce minor microsecond precision discrepancies when advancing time. If the initial `datetime.now()` or subsequent `datetime.now()` calls include non-zero microseconds, direct comparisons of `timedelta`s to exact second values can fail, leading to `AssertionError`s. This often happens because the patching mechanism might handle sub-second precision differently when freezing vs. advancing.
fix
When asserting time advancement with `freezegun`, consider using a small tolerance for `timedelta` comparisons (e.g., `assert abs((after_tick - start_time) - datetime.timedelta(seconds=5)) < datetime.timedelta(microseconds=100)`) or truncate `datetime` objects to milliseconds/seconds before comparison to avoid microsecond-level precision issues.
affects: All versions
gotchaFreezegun may introduce minor microsecond discrepancies when advancing time, particularly when using `freezegun.move_time()` or performing arithmetic with high-precision `datetime` objects. This can lead to `AssertionError` if tests expect exact equality with `datetime.timedelta` comparisons, even for seemingly precise time advancements. The observed discrepancies are typically very small, on the order of a few microseconds.
fix
Instead of asserting for exact equality with `datetime.timedelta`, consider comparing with a small tolerance for microsecond differences (e.g., `assert abs(actual_timedelta - expected_timedelta) < datetime.timedelta(microseconds=10)`). Alternatively, round `datetime` objects to a desired precision (e.g., seconds or milliseconds) before comparison if microsecond accuracy is not critical for the test.
affects: All versions
Errors
Common errors & fixes
datetime.datetime.now() not frozen freezegun
The `datetime` module or its components (like `datetime.datetime` or `datetime.date`) were imported into the module under test at module load time, before `freezegun` had a chance to patch them.
fix
Ensure that `datetime` imports in the code under test occur within the scope of the `freezegun.freeze_time` decorator or context manager, or that `freezegun` is initialized early enough to patch already loaded modules.
AttributeError: type object 'datetime.datetime' has no attribute 'datetime'
This error typically occurs when `datetime` is imported using `from datetime import datetime` and then an attempt is made to access `datetime.datetime.now()`. When `datetime.datetime` is imported directly, `datetime` itself refers to the class, not the module, so `datetime.datetime` is invalid.
fix
Change the import statement to `import datetime` and then call `datetime.datetime.now()`, or if you import `from datetime import datetime`, directly call `datetime.now()` without the module prefix.
RuntimeError: 'datetime' module was frozen, but the 'datetime' module itself was replaced
This error indicates a conflict where `freezegun` has already frozen the `datetime` module, but another library or part of the test setup subsequently replaces the `datetime` module entirely, breaking `freezegun`'s patch.
fix
Investigate if another mocking library or a complex test fixture is also manipulating the `datetime` module. Ensure `freezegun` is the last to apply its patches, or use `freezegun.configure(default_ignore_list=[...])` or the `ignore` parameter on `freeze_time` to exclude conflicting modules.
freezegun time.time() not frozen in thread
By default, `freezegun` adds `threading` to its ignore list to prevent deadlocks and unexpected behavior, meaning `time.time()` calls originating from within the `threading` module (or code that is considered part of `threading`'s stack) will not be frozen.
fix
If you explicitly need to freeze time within threads, you can remove `threading` from the ignore list using `freeze_time(..., ignore=['list', 'of', 'modules'] - {'threading'})` or `freezegun.configure(default_ignore_list=list(set(freezegun.config.default_ignore_list) - {'threading'}))`. Exercise caution as this can lead to deadlocks if `threading` internals are also frozen.
Upgrade
Version history
1.5.5latest on PyPI
Audit
Dependencies
pythonrequiredRequires Python 3.8 or newer.
python-dateutilrequiredUsed internally for parsing flexible date/time strings.
pytzoptionalFallback for timezone handling on Python versions older than 3.9, which lack `zoneinfo`.
Agent activity
11 hits · last 30 days
seranking-bot
4
node
2
ahrefsbot
2
Amazon
1
amazonbot
1
Resources