Skip to main content

A fast alternative to freezegun that wraps libfaketime.

Project description

https://img.shields.io/travis/simon-weber/python-libfaketime.svg https://img.shields.io/pypi/v/libfaketime.svg

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

  • 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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

libfaketime-0.5.0.tar.gz (64.8 kB view hashes)

Uploaded Source

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page