A fast alternative to freezegun that wraps libfaketime.
Project description
python-libfaketime is a wrapper of libfaketime for python. Some brief details:
Linux and OS X, Pythons 2.7, 3.4, 3.5, 3.6.
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)
Performances
libfaketime serves as a fast drop-in replacement for 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 easiest way is to use the pytest-libfaketime plugin. This way you wont have to edit your conftest.py or call reexec_if_needed yourself. Just plug and play.
$ pip install pytest-libfaketime
You can also reexec 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)
Migration from freezegun
find . -type f -name "*.py" -exec sed -i 's/freezegun/libfaketime/g' "{}" \;
How to avoid re-exec
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)
$ pytest # ...or any other code that imports libfaketime
Contributing and testing
Contributions are highly welcomed. You should compile libfaketime before running tests:
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.
Known Issues
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.
Changelog
Semantic versioning is used.
0.5.0
released 2017-09-10
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
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
prevent distribution of test directory: https://github.com/simon-weber/python-libfaketime/pull/4
0.1.0
released 2015-06-23
add global start/stop callbacks
0.0.3
released 2015-03-28
initial packaged release
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.