Metadata-Version: 1.1
Name: hiro
Version: 1.0.1
Summary: time manipulation utilities for testing in python
Home-page: http://hiro.readthedocs.org
Author: Ali-Akber Saifee
Author-email: ali@indydevs.org.com
License: MIT
Description: .. |ci| image:: https://github.com/alisaifee/hiro/workflows/CI/badge.svg?branch=master
            :target: https://github.com/alisaifee/hiro/actions?query=branch%3Amaster+workflow%3ACI
        .. |coveralls| image:: https://img.shields.io/coveralls/alisaifee/hiro/master.svg?style=flat-square
            :target: https://coveralls.io/r/alisaifee/hiro?branch=master
        .. |license| image:: https://img.shields.io/pypi/l/hiro.svg?style=flat-square
            :target: https://pypi.python.org/pypi/hiro
        .. |pypi| image:: https://img.shields.io/pypi/v/hiro.svg?style=flat-square
            :target: https://pypi.python.org/pypi/hiro
        .. |docs| image:: https://readthedocs.org/projects/hiro/badge
            :target: https://hiro.readthedocs.org
        
        
        ********************************************************
        Hiro - time manipulation utilities for testing in python
        ********************************************************
        |ci| |coveralls| |pypi| |docs| |license|
        
           Yatta!
        
           -- Hiro Nakamura
        
        
        
        ====================
        Hiro context manager
        ====================
        
        
        Timeline context
        ================
        The ``hiro.Timeline`` context manager hijacks a few commonly used time functions
        to allow time manipulation within its context. Specifically ``time.sleep``, ``time.time``,
        ``time.gmtime``, ``datetime.now``, ``datetime.utcnow`` and ``datetime.today`` behave according the configuration of the context.
        
        The context provides the following manipulation options:
        
        * ``rewind``: accepts seconds as an integer or a ``timedelta`` object.
        * ``forward``: accepts seconds as an integer or a ``timedelta`` object.
        * ``freeze``: accepts a floating point time since epoch or ``datetime`` or ``date`` object to freeze the time at.
        * ``unfreeze``: resumes time from the point it was frozen at.
        * ``scale``: accepts a floating point to accelerate/decelerate time by. ``> 1 = acceleration,  < 1 = deceleration``
        * ``reset``: resets all time alterations.
        
        .. code-block:: python
        
            import hiro
            from datetime import timedelta, datetime
            import time
        
            datetime.now().isoformat()
            # OUT: '2013-12-01T06:55:41.706060'
            with hiro.Timeline() as timeline:
        
                # forward by an hour
                timeline.forward(60*60)
                datetime.now().isoformat()
                # OUT: '2013-12-01T07:55:41.707383'
        
                # jump forward by 10 minutes
                timeline.forward(timedelta(minutes=10))
                datetime.now().isoformat()
                # OUT: '2013-12-01T08:05:41.707425'
        
                # jump to yesterday and freeze
                timeline.freeze(datetime.now() - timedelta(hours=24))
                datetime.now().isoformat()
                # OUT: '2013-11-30T09:15:41'
        
                timeline.scale(5) # scale time by 5x
                time.sleep(5) # this will effectively only sleep for 1 second
        
                # since time is frozen the sleep has no effect
                datetime.now().isoformat()
                # OUT: '2013-11-30T09:15:41'
        
                timeline.rewind(timedelta(days=365))
        
                datetime.now().isoformat()
                # OUT: '2012-11-30T09:15:41'
        
        
        
        To reduce the amount of statements inside the context, certain timeline setup
        tasks can be done via the constructor and/or by using the fluent interface.
        
        .. code-block:: python
        
            import hiro
            import time
            from datetime import timedelta, datetime
        
            start_point = datetime(2012,12,12,0,0,0)
            my_timeline = hiro.Timeline(scale=5).forward(60*60).freeze()
            with my_timeline as timeline:
                print datetime.now()
                # OUT: '2012-12-12 01:00:00.000315'
                time.sleep(5) # effectively 1 second
                # no effect as time is frozen
                datetime.now()
                # OUT: '2012-12-12 01:00:00.000315'
                timeline.unfreeze()
                # back to starting point
                datetime.now()
                # OUT: '2012-12-12 01:00:00.000317'
                time.sleep(5) # effectively 1 second
                # takes effect (+5 seconds)
                datetime.now()
                # OUT: '2012-12-12 01:00:05.003100'
        
        
        ``Timeline`` can additionally be used as a decorator
        
        .. code-block:: python
        
            import hiro
            import time, datetime
        
            @hiro.Timeline(scale=50000)
            def sleeper():
                datetime.datetime.now()
                # OUT: '2013-11-30 14:27:43.409291'
                time.sleep(60*60) # effectively 72 ms
                datetime.datetime.now()
                # OUT: '2013-11-30 15:28:36.240675'
        
            @hiro.Timeline()
            def sleeper_aware(timeline):
                datetime.datetime.now()
                # OUT: '2013-11-30 14:27:43.409291'
                timeline.forward(60*60)
                datetime.datetime.now()
                # OUT: '2013-11-30 15:28:36.240675'
        
        ==============
        Hiro executors
        ==============
        
        In order to execute certain callables within a ``Timeline`` context, two
        shortcut functions are provided.
        
        * ``run_sync(factor=1, callable, *args, **kwargs)``
        * ``run_async(factor=1, callable, *args, **kwargs)``
        
        Both functions return a ``ScaledRunner`` object which provides the following methods
        
        * ``get_execution_time``: The actual execution time of the ``callable``
        * ``get_response`` (will either return the actual return value of ``callable`` or raise the exception that was thrown)
        
        ``run_async`` returns a derived class of ``ScaledRunner`` that additionally provides the following methods
        
        * ``is_running``: ``True/False`` depending on whether the callable has completed execution
        * ``join``: blocks until the ``callable`` completes execution
        
        
        Example
        =======
        
        .. code-block:: python
        
        
            import hiro
            import time
        
            def _slow_function(n):
                time.sleep(n)
                if n > 10:
                    raise RuntimeError()
                return n
        
            runner = hiro.run_sync(10, _slow_function, 10)
            runner.get_response()
            # OUT: 10
        
            # due to the scale factor 10 it only took 1s to execute
            runner.get_execution_time()
            # OUT: 1.1052658557891846
        
            runner = hiro.run_async(10, _slow_function, 11)
            runner.is_running()
            # OUT: True
            runner.join()
            runner.get_execution_time()
            # OUT: 1.1052658557891846
            runner.get_response()
            # OUT: Traceback (most recent call last):
            # ....
            # OUT:   File "<input>", line 4, in _slow_function
            # OUT: RuntimeError
        
        
        
        .. :changelog:
        
        Changelog
        =========
        
        v1.0.1
        ------
        Release Date: 2023-01-11
        
        Compatibility:
        
          * Update package classifiers to reflect python version support
        
        v1.0.0
        ------
        Release Date: 2023-01-10
        
        Compatibility:
        
          * Drop support for python < 3.7
          * Update sources to not need six for compatibility
        
        Chores:
          * Standardize linting
          * Add Asia/Shanghai to CI matrix
        
        
        v0.5.1
        ------
        Release Date: 2019-10-10
        
        Code cleanup
        
        v0.5
        ----
        Release Date: 2017-07-26
        
        Bug Fix:
          * Account for microsecond resolution (`Pull Request 3 <https://github.com/alisaifee/hiro/pull/3>`_)
        
        v0.1.8
        ------
        Release Date: 2015-06-07
        
          * Add Python 3.x support
        
        v0.1.5
        ------
        Release Date: 2014-04-03
        
        Bug Fix:
        
          * Imports from time weren't being patched.
        
        v0.1.3
        ------
        Release Date: 2014-04-01
        
        Enhanced timeline decorator to pass generated timeline
        to decorated function
        
        v0.1.2
        ------
        Release Date: 2014-02-20
        
        * Added blacklist for unpatchable modules
        * CI improvements
        * removed ScaledTimeline
        
        v0.1.1
        ------
        Release Date: 2013-12-05
        
        Added pypy support
        
        v0.0.3
        ------
        Release Date: 2013-11-30
        
        Allow ScaledTimeline to be used as a decorator
        
        v0.0.1
        ------
        Release Date: 2013-11-30
        
        Initial Release
        
        
        
        
Platform: UNKNOWN
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: End Users/Desktop
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Topic :: Software Development :: Testing
Classifier: Topic :: Software Development :: Libraries
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: Implementation :: PyPy
