Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

hiro

Package Overview
Dependencies
Maintainers
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

hiro

time manipulation utilities for testing in python

  • 1.1.1
  • PyPI
  • Socket score

Maintainers
1

.. |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.1.1

Release Date: 2023-01-11

Chore:

  • Fix github release action

v1.1.0

Release Date: 2023-01-11

Features:

  • Patch time.time_ns, time.monotonic, time.monotonic_ns, time.localtime

Bug Fix:

  • Ensure time.gmtime and time.localtime work with 0 values
  • Ensure Timeline can be instantiated with start=0 to reflect time=0
  • Improve naming of threaded classes/functions

Deprecation:

  • Deprecated run_async in favor of run_threaded

v1.0.2

Release Date: 2023-01-11

Chores:

  • Update documentation theme

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

FAQs


Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc