Metadata-Version: 2.1
Name: libfaketime
Version: 2.0.0
Summary: A fast alternative to freezegun that wraps libfaketime.
Home-page: http://pypi.python.org/pypi/libfaketime/
Author: Simon Weber
Author-email: simon@simonmweber.com
License: GPLv2
Platform: UNKNOWN
Classifier: License :: OSI Approved :: GNU General Public License v2 (GPLv2)
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Topic :: Software Development :: Libraries :: Python Modules
License-File: LICENSE

python-libfaketime: fast date/time mocking
==========================================

.. image:: https://img.shields.io/travis/simon-weber/python-libfaketime.svg
        :target: https://travis-ci.org/simon-weber/python-libfaketime
.. image:: https://img.shields.io/pypi/v/libfaketime.svg
        :target: https://pypi.python.org/pypi/libfaketime
.. image:: https://img.shields.io/badge/dynamic/json.svg?label=release&query=%24.status&maxAge=43200&uri=https%3A%2F%2Fwww.repominder.com%2Fbadge%2FeyJ1c2VyX2lkIjogMiwgInJlcG9faWQiOiA3OX0%3D%2F&link=https%3A%2F%2Fwww.repominder.com%2F
        :target: https://www.repominder.com

python-libfaketime is a wrapper of `libfaketime <https://github.com/wolfcw/libfaketime>`__ for python.
Some brief details:

* Linux and OS X, Pythons 3.5 through 3.8, pypy and pypy3
* Mostly compatible with `freezegun <https://github.com/spulec/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 <https://gist.github.com/simon-weber/8d43e33448684f85718417ce1a072bc8>`__).


Installation
------------

.. code-block:: sh

    $ pip install libfaketime

Usage
-----

.. code-block:: python

    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)


Performance
-----------

libfaketime tends to be significantly faster than `freezegun <https://github.com/spulec/freezegun>`__.
Here's the output of a `totally unscientific benchmark <https://github.com/simon-weber/python-libfaketime/blob/master/benchmark.py>`__ on my laptop:

.. code-block:: sh

    $ 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 <https://gitlab.com/yaal/pytest-libfaketime>`__ plugin will automatically configure python-libfaketime for you:

.. code-block:: sh

    $ pip install pytest-libfaketime


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

.. code-block:: python

    # 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:

.. code-block::

    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:

.. code-block:: bash

    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:

.. code-block:: sh

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

You can easily put this in a script like:

.. code-block:: sh

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


Contributing and testing
------------------------

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

.. code-block:: bash

    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:

Changelog
---------

`Semantic versioning <http://semver.org/>`__ is used.

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 <https://github.com/simon-weber/python-libfaketime/pull/57>`__
- fix compatibility with non-pytz tzinfo objects: `\#58 <https://github.com/simon-weber/python-libfaketime/pull/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 <https://github.com/simon-weber/python-libfaketime/pull/49>`__

1.1.0
+++++
released 2018-10-07

- decorated classes can access the fake_time object with ``self._faked_time``: `\#47 <https://github.com/simon-weber/python-libfaketime/pull/47>`__

1.0.0
+++++
released 2018-06-16

- **backwards incompatible**: the monotonic clock is no longer mocked: `\#45 <https://github.com/simon-weber/python-libfaketime/pull/45>`__
- ensure TZ is set to a valid timezone: `\#46 <https://github.com/simon-weber/python-libfaketime/pull/46>`__

0.5.2
+++++
released 2018-05-19

- fix a bug causing incorrect times after unpatching under python 3.6+: `\#43 <https://github.com/simon-weber/python-libfaketime/pull/43>`__
- fix compilation under gcc8: `\#44 <https://github.com/simon-weber/python-libfaketime/pull/44>`__

0.5.1
+++++
released 2018-01-19

- fix usage as a class decorator : `\#41 <https://github.com/simon-weber/python-libfaketime/pull/41>`__

0.5.0
+++++
released 2017-09-10

- alias fake_time for freeze_time: `\#31 <https://github.com/simon-weber/python-libfaketime/pull/31>`__
- add tz_offset parameter: `\#36 <https://github.com/simon-weber/python-libfaketime/pull/36>`__

0.4.4
+++++
released 2017-07-16

- allow contextlib2 as an alternative to contextdecorator: `\#30 <https://github.com/simon-weber/python-libfaketime/pull/30>`__

0.4.3
+++++
released 2017-07-07

- add macOS Sierra compatibility: `\#29 <https://github.com/simon-weber/python-libfaketime/pull/29>`__

0.4.2
+++++
released 2016-06-30

- fix only_main_thread=False: `\#24 <https://github.com/simon-weber/python-libfaketime/pull/24>`__

0.4.1
+++++
released 2016-05-02

- fix deadlocks from uuid.uuid1 when faking time: `\#14 <https://github.com/simon-weber/python-libfaketime/pull/14>`__
- remove contextdecorator dependency on python3: `\#15 <https://github.com/simon-weber/python-libfaketime/pull/15>`__

0.4.0
+++++
released 2016-04-02

- freezegun's tick() is now supported; see `their docs <https://github.com/spulec/freezegun/blob/f1f5148720dd715cfd6dc03bf1861dbedfaad493/README.rst#manual-ticks>`__ 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


