A fast alternative to freezegun that wraps libfaketime.
python-libfaketime is a wrapper of libfaketime for python.
Install with pip:
$ pip install libfaketime
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 get_tomorrow(): return datetime.date.today() + datetime.timedelta(days=1) @fake_time('2014-01-01 00:00:00') def test_get_tomorrow(): assert get_tomorrow() == datetime.date(2014, 1, 2)
$ 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
Some brief details:
It’s easiest to reexec from inside the pytest_configure hook:
# conftest.py from libfaketime import reexec_if_needed def pytest_configure(): reexec_if_needed()
Sometimes, re-exec does unexpected things. You can avoid those problems by preloading libfaketime yourself. The environment variables you need
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 FAKETIME_DID_REEXEC=true
You can use them as such:
$ eval $(python-libfaketime) $ nosetests # ...or any other code that imports libfaketime
It was found that calling
uuid.uuid1() multiple times while in a fake_time context could result in a deadlock. This situation only occured for users with
a system level uuid1 library. In order to combat this issue, python-libfaketime temporarily disables the system level library by patching
_uuid_generate_time to None while in
the fake_time context.
Semantic versioning is used.