Skip to main content

python-libfaketime: fast date/time mocking

github actions pypi repominder

python-libfaketime is a wrapper of libfaketime for python. Some brief details:

  • Linux and OS X, Pythons 3.8 through 3.12, pypy and pypy3
  • Mostly compatible with freezegun.
  • Microsecond resolution.
  • Accepts datetimes and strings that can be parsed by dateutil.
  • Not threadsafe.
  • Will break profiling. A workaround: use libfaketime.{begin, end}_callback to disable/enable your profiler (nosetest example).

Installation

$ pip install libfaketime

Usage

import datetime
from libfaketime import fake_time, reexec_if_needed

# libfaketime needs to be preloaded by the dynamic linker.
# This will exec the same command, but with the proper environment variables set.
# You can also skip this and manually manage your env (see "How to avoid re-exec").
reexec_if_needed()

def test_datetime_now():

    # fake_time can be used as a context_manager
    with fake_time('1970-01-01 00:00:01'):

        # Every calls to a date or datetime function returns the mocked date
        assert datetime.datetime.utcnow() == datetime.datetime(1970, 1, 1, 0, 0, 1)
        assert datetime.datetime.now() == datetime.datetime(1970, 1, 1, 0, 0, 1)
        assert time.time() == 1


# fake_time can also be used as a decorator
@fake_time('1970-01-01 00:00:01', tz_offset=12)
def test_datetime_now_with_offset():

    # datetime.utcnow returns the mocked datetime without offset
    assert datetime.datetime.utcnow() == datetime.datetime(1970, 1, 1, 0, 0, 1)

    # datetime.now returns the mocked datetime with the offset passed to fake_time
    assert datetime.datetime.now() == datetime.datetime(1970, 1, 1, 12, 0, 1)

remove_vars

By default, reexec_if_needed removes the LD_PRELOAD variable after the re-execution, to keep your environment as clean as possible. You might want it to stick around, for example when using parallelized tests that use subprocess like pytest-xdist, and simply for tests where subprocess is called. To keep them around, pass remove_vars=False like:

reexec_if_needed(remove_vars=False)

quiet

To avoid displaying the informative text when re-executing, you can set the quiet parameter:

reexec_if_needed(quiet=True)

timestamp_file

A common time can be shared between several execution contexts by using a file to store the time to mock, instead of environment variables. This is useful to control the time of a running process for instance. Here is a schematized use case:

reexec_if_needed(remove_vars=False)

with fake_time("1970-01-01 00:00:00", timestamp_file="/tmp/timestamp"):
    subprocess.run("/some/server/process")

with fake_time("2000-01-01 00:00:00", timestamp_file="/tmp/timestamp"):
    assert request_the_server_process_date() == "2000-01-01 00:00:00"

Performance

libfaketime tends to be significantly faster than freezegun. Here's the output of a totally unscientific benchmark on my laptop:

$ python benchmark.py
re-exec with libfaketime dependencies
timing 1000 executions of <class 'libfaketime.fake_time'>
0.021755 seconds

$ python benchmark.py freezegun
timing 1000 executions of <function freeze_time at 0x10aaa1140>
6.561472 seconds

Use with py.test

The pytest-libfaketime plugin will automatically configure python-libfaketime for you:

$ pip install pytest-libfaketime

Alternatively, you can reexec manually from inside the pytest_configure hook:

# conftest.py
import os
import libfaketime

def pytest_configure():
    libfaketime.reexec_if_needed()
    _, env_additions = libfaketime.get_reload_information()
    os.environ.update(env_additions)

Use with tox

In your tox configuration file, under the testenv bloc, add the libfaketime environment variables to avoid re-execution:

setenv =
    LD_PRELOAD = {envsitepackagesdir}/libfaketime/vendor/libfaketime/src/libfaketime.so.1
    DONT_FAKE_MONOTONIC = 1
    FAKETIME_DID_REEXEC = true

Migration from freezegun

python-libfaketime should have the same behavior as freezegun when running on supported code. To migrate to it, you can run:

find . -type f -name "*.py" -exec sed -i 's/freezegun/libfaketime/g' "{}" \;

How to avoid re-exec

In some cases - especially when your tests start other processes - re-execing can cause unexpected problems. To avoid this, you can preload the necessary environment variables yourself. The necessary environment for your system can be found by running python-libfaketime on the command line:

$ python-libfaketime
export LD_PRELOAD="/home/foo/<snip>/vendor/libfaketime/src/libfaketime.so.1"
export DONT_FAKE_MONOTONIC="1"
export FAKETIME_NO_CACHE="1"
export FAKETIME_DID_REEXEC=true

You can easily put this in a script like:

$ eval $(python-libfaketime)
$ pytest  # ...or any other code that imports libfaketime

Contributing and testing

Contributions are welcome! You should compile libfaketime before running tests:

git submodule init --update
# For Linux:
env FAKETIME_COMPILE_CFLAGS="-UFAKE_STAT -UFAKE_UTIME -UFAKE_SLEEP" make -C libfaketime/vendor/libfaketime
# For macOS
env make -C libfaketime/vendor/libfaketime

Then you can install requirements with pip install -r requirements.txt and use pytest and tox to run the tests.

uuid1 deadlock

Calling uuid.uuid1() multiple times while in a fake_time context can result in a deadlock when an OS-level uuid library is available. To avoid this, python-libtaketime will monkeypatch uuid._uuid_generate_time (or similar, it varies by version) to None inside a fake_time context. This may slow down uuid1 generation but should not affect correctness.

Changelog

Semantic versioning is used.

3.0.1

released 2026-08-19

  • fix format restoration from nested contexts: #88

3.0.0

released 2025-01-20

Thanks for @azmeuk for their contributions to this release.

  • breaking: drop support for python 3.8
  • disable FAKETIME_FORCE_MONOTONIC_FIX to attempt to fix a performance regression in 2.1.0: #81
  • add support for python 3.13

2.1.0

released 2024-05-17

Thanks for @azmeuk for all their contributions to this release!

  • add support for timestamp files, which enables freezing time across subprocesses: #78
  • upgrade underlying libfaketime to 0.9.10 without modifications: #75
  • add a quiet param to rexec_if_needed: #72

2.0.0

released 2020-04-17

  • breaking: drop python 2.7 support
  • set LD_LIBRARY_PATH on linux to support paths containing spaces: #57
  • fix compatibility with non-pytz tzinfo objects: #58

1.2.1

released 2019-01-20

  • fix a deadlock on python 3.7+

1.2.0

released 2018-10-28

  • offset-aware datetimes now properly fake the timezone as well: #49

1.1.0

released 2018-10-07

  • decorated classes can access the fake_time object with self._faked_time: #47

1.0.0

released 2018-06-16

  • backwards incompatible: the monotonic clock is no longer mocked: #45
  • ensure TZ is set to a valid timezone: #46

0.5.2

released 2018-05-19

  • fix a bug causing incorrect times after unpatching under python 3.6+: #43
  • fix compilation under gcc8: #44

0.5.1

released 2018-01-19

  • fix usage as a class decorator : #41

0.5.0

released 2017-09-10

  • alias fake_time for freeze_time: #31
  • add tz_offset parameter: #36

0.4.4

released 2017-07-16

  • allow contextlib2 as an alternative to contextdecorator: #30

0.4.3

released 2017-07-07

  • add macOS Sierra compatibility: #29

0.4.2

released 2016-06-30

  • fix only_main_thread=False: #24

0.4.1

released 2016-05-02

  • fix deadlocks from uuid.uuid1 when faking time: #14
  • remove contextdecorator dependency on python3: #15

0.4.0

released 2016-04-02

  • freezegun's tick() is now supported; see their docs for usage.

0.3.0

released 2016-03-04

  • invoking libfaketime from the command line will now print the necessary environment to avoid a re-exec.

0.2.1

released 2016-03-01

  • python 3 support

0.1.1

released 2015-09-11

0.1.0

released 2015-06-23

  • add global start/stop callbacks

0.0.3

released 2015-03-28

  • initial packaged release

Release files for libfaketime 3.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for libfaketime 3.0.1
File Size Uploaded
libfaketime-3.0.1.tar.gz 75.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for libfaketime 3.0.1
File Interpreter ABI Platform
libfaketime-3.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 168.9 kB

Release files / libfaketime-3.0.1.tar.gz

Download URL libfaketime-3.0.1.tar.gz
Size 75.9 kB
Tags Source
SHA-256 checksum
How to use checksums
49c2b06250bd5a1206efe5ecfdc575850517081b50b42c6c58718be1a4a09fbd
BLAKE2b-256 checksum
How to use checksums
df85b46c502837430823420be8ba856479819acc5a5fa4e46de167b0188f4ba3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/5.1.0 CPython/3.8.7

Release files / libfaketime-3.0.1-py3-none-any.whl

Download URL libfaketime-3.0.1-py3-none-any.whl
Size 93.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5eed7c17f3d4ba0f6f828de4975f69a622b06b1e792674e6c1b069c0689fab79
BLAKE2b-256 checksum
How to use checksums
87a3af0d453324bff5ee0c1ae51be5604df56c5c6d1d5f61e430a1b96a80e2ac
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/5.1.0 CPython/3.8.7

Release history Release notifications | RSS feed

This release

3.0.1 This release

2 release files

3.0.0

2 release files

2.1.0

2 release files

2.0.0

1 release file

1.2.1

1 release file

1.2.0

1 release file

1.0.0

1 release file

0.5.2

1 release file

0.5.1

1 release file

0.5.0

1 release file

0.4.4

1 release file

0.4.3

1 release file

0.4.2

1 release file

0.4.1

1 release file

0.4.0

1 release file

0.3.0

1 release file

0.2.1

1 release file

0.1.1

1 release file

0.1.0

1 release file

0.0.3

1 release file

0.0.2

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page