Skip to content

Commit 6b69247

Browse files
authored
refactor for v0.2.0 (#2)
* refactor for v0.2.0
1 parent a515df3 commit 6b69247

10 files changed

Lines changed: 966 additions & 263 deletions

File tree

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2019 HH-MWB
3+
Copyright (c) 2019-2021 HH-MWB
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 43 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,70 @@
1-
![TimeRun](https://user-images.githubusercontent.com/50187675/62002266-8f926b80-b0ce-11e9-9e54-3b7eeb3a2ae1.png)
1+
<p align="center">
2+
<a href="https://github.com/HH-MWB/timerun">
3+
<img src="https://user-images.githubusercontent.com/50187675/62002266-8f926b80-b0ce-11e9-9e54-3b7eeb3a2ae1.png" alt="TimeRun">
4+
</a>
5+
</p>
26

3-
TimeRun is a [Python](https://www.python.org) library for elapsed time measurement.
7+
<p align="center"><strong>TimeRun</strong> - <em>Python library for elapsed time measurement.</em></p>
48

5-
* Measure elapsed time and format output in **one line** yet providing the highest resolution for time measurement
6-
* All in a single file with no dependencies other than [Python Standard Library](https://docs.python.org/3/library/)
9+
<p align="center">
10+
<a href="https://github.com/HH-MWB/timerun/blob/master/LICENSE"><img alt="License" src="https://img.shields.io/pypi/l/timerun.svg"></a>
11+
<a href="https://pypi.org/project/timerun/"><img alt="PyPI Latest Release" src="https://img.shields.io/pypi/v/timerun.svg"></a>
12+
<a href="https://pypi.org/project/timerun/"><img alt="Package Status" src="https://img.shields.io/pypi/status/timerun.svg"></a>
13+
<a href="https://github.com/psf/black/"><img alt="Code style: black" src="https://img.shields.io/badge/code%20style-black-000000.svg"></a>
14+
<a href="https://pycqa.github.io/isort/"><img alt="Imports: isort" src="https://img.shields.io/badge/%20imports-isort-%231674b1"></a>
15+
</p>
716

8-
## Features
17+
TimeRun is a simple, yet elegant elapsed time measurement library for [Python](https://www.python.org). It is distributed as a single file module and has no dependencies other than the [Python Standard Library](https://docs.python.org/3/library/).
918

10-
* Elapsed Time Estimator
11-
* Measure elapsed time with sleep
12-
* Measure elapsed time without sleep
13-
* Elapsed Time Formatter
14-
* Format time into hours, minutes, seconds and nanoseconds
15-
* Hide days part if time is less than 1 day
16-
* Shortcut to Time Measurement
17-
* Measure elapsed time for a code block
18-
* Measure elapsed time for a function
19+
- **Elapsed Time**: Customized time delta which represents elapsed time in nanoseconds.
20+
- **Stopwatch**: An elapsed time measurer with the highest available resolution.
21+
- **Timer**: Convenient syntax to capture measured elapsed time result and save it.
1922

20-
## Installation
23+
## Setup
2124

22-
Install TimeRun from [Python Package Index](https://pypi.org/project/timerun/)
25+
### Prerequisites
26+
27+
The only prerequisite to use TimeRun is running **Python 3.7+**.
28+
29+
### Installation
30+
31+
Install TimeRun from [Python Package Index](https://pypi.org/project/timerun/):
2332

2433
```
2534
pip install timerun
2635
```
2736

28-
Install TimeRun from [Source Code](https://github.com/HH-MWB/timerun)
37+
Install TimeRun from [Source Code](https://github.com/HH-MWB/timerun):
2938

3039
```
3140
python setup.py install
3241
```
3342

34-
## Examples
43+
## Quickstart
3544

36-
### Measure code block execution time
45+
### Measure Code Block
3746

3847
```python
39-
from timerun import time_code
40-
41-
with time_code('countdown'):
42-
n = 1e6
43-
while n > 0:
44-
n -= 1
45-
```
46-
47-
```
48-
countdown - 00:00:00.110983022
48+
>>> from timerun import Timer
49+
>>> with Timer() as timer:
50+
... pass # put your code here
51+
>>> print(timer.duration)
52+
0:00:00.000000100
4953
```
5054

51-
### Measure function execution time
55+
### Measure Function
5256

5357
```python
54-
from timerun import time_func
55-
56-
@time_func
57-
def countdown():
58-
n = 1e6
59-
while n > 0:
60-
n -= 1
61-
62-
countdown()
63-
```
64-
65-
```
66-
__main__.countdown - 00:00:00.069651527
58+
>>> from timerun import Timer
59+
>>> timer = Timer()
60+
>>> @timer
61+
... def func():
62+
... pass # put your code here
63+
>>> func()
64+
>>> print(timer.duration)
65+
0:00:00.000000100
6766
```
6867

6968
## License
7069

71-
This project is licensed under the MIT License - see the [LICENSE](https://github.com/HH-MWB/timerun/blob/master/LICENSE) file for details
70+
This project is licensed under the MIT License - see the [LICENSE](https://github.com/HH-MWB/timerun/blob/master/LICENSE) file for details.

setup.cfg

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
[metadata]
2+
name = timerun
3+
version = attr: timerun.__version__
4+
url = https://github.com/HH-MWB/timerun
5+
author = HH-MWB
6+
author_email = h.hong@mail.com
7+
classifiers =
8+
Development Status :: 3 - Alpha
9+
Intended Audience :: Developers
10+
License :: OSI Approved :: MIT License
11+
Operating System :: OS Independent
12+
license = MIT
13+
license_file = LICENSE
14+
description = TimeRun is a Python library for elapsed time measurement.
15+
long_description = file: README.md
16+
long_description_content_type = text/markdown
17+
platforms = any
18+
19+
[options]
20+
zip_safe = true
21+
python_requires = >= 3.7
22+
include_package_data = false
23+
py_modules = timerun

setup.py

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,5 @@
11
#!/usr/bin/env python
2-
# -*- coding: utf-8 -*-
32

43
from setuptools import setup
5-
from timerun import __version__
64

7-
8-
with open('README.md', 'r') as f:
9-
long_description = f.read()
10-
11-
12-
setup(
13-
name='timerun',
14-
version=__version__,
15-
author='HH-MWB',
16-
author_email='h.hong@mail.com',
17-
description='Library for execution time measurement',
18-
long_description=long_description,
19-
long_description_content_type='text/markdown',
20-
url='https://github.com/HH-MWB/timerun',
21-
classifiers=[
22-
'Programming Language :: Python :: 3',
23-
'License :: OSI Approved :: MIT License',
24-
'Operating System :: OS Independent',
25-
],
26-
py_modules=['timerun'],
27-
python_requires='>=3.4',
28-
)
5+
setup()

tests/__init__.py

Whitespace-only changes.

tests/conftest.py

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
"""A collection of shared PyTest fixtures for timerun."""
2+
3+
from contextlib import contextmanager
4+
from typing import Callable, ContextManager, Iterable, Iterator, Tuple
5+
from unittest.mock import Mock
6+
7+
from pytest import MonkeyPatch, fixture
8+
9+
from timerun import ElapsedTime, Stopwatch, Timer
10+
11+
__all__: Tuple[str, ...] = (
12+
# -- Patcheres --
13+
"patch_clock",
14+
"patch_split",
15+
# -- Initiated Instances --
16+
"stopwatch",
17+
"timer",
18+
# -- Elapsed Time --
19+
"elapsed_1_ns",
20+
"elapsed_100_ns",
21+
"elapsed_1_ms",
22+
"elapsed_1_pt_5_ms",
23+
"elapsed_1_sec",
24+
)
25+
26+
27+
# =========================================================================== #
28+
# Patcheres #
29+
# =========================================================================== #
30+
31+
32+
@fixture
33+
def patch_clock(monkeypatch: MonkeyPatch) -> Callable[[int], ContextManager]:
34+
"""Patch the clock method in Stopwatch.
35+
36+
Parameters
37+
----------
38+
monkeypatch : MonkeyPatch
39+
The fixture has been used to patch the clock method.
40+
41+
Returns
42+
-------
43+
Callable[[int], ContextManager]
44+
A context manager takes integer argument and patch that value as
45+
the return value of the clock method.
46+
47+
Examples
48+
--------
49+
>>> with patch_clock(elapsed_ns=1):
50+
... pass
51+
"""
52+
53+
@contextmanager
54+
def patch(elapsed_ns: int) -> Iterator[None]:
55+
"""Patch clock method through monkeypatch context.
56+
57+
Parameters
58+
----------
59+
elapsed_ns : int
60+
The value should be returned by the clock method.
61+
"""
62+
monkeypatch.setattr(Stopwatch, "_clock", lambda self: elapsed_ns)
63+
yield
64+
65+
return patch
66+
67+
68+
@fixture
69+
def patch_split(
70+
monkeypatch: MonkeyPatch,
71+
) -> Callable[[Iterable[int]], ContextManager]:
72+
"""Patch the split method in Timer.
73+
74+
Parameters
75+
----------
76+
monkeypatch : MonkeyPatch
77+
The fixture has been used to patch the split method.
78+
79+
Returns
80+
-------
81+
Callable[[Iterable[int]], ContextManager]
82+
A context manager takes a list of integers as nanoseconds and
83+
patch those as the return values of the elapse method.
84+
85+
Examples
86+
--------
87+
>>> with patch_split(elapsed_times=[100, 200, 300]):
88+
... pass
89+
"""
90+
91+
@contextmanager
92+
def patch(elapsed_times: Iterable[int]) -> Iterator[None]:
93+
"""Patch split method through monkeypatch context.
94+
95+
Parameters
96+
----------
97+
elapsed_times : Iterable[int]
98+
The nanoseconds should be returned by the split method.
99+
"""
100+
mock_stopwatch = Mock(spec=["reset", "split"])
101+
mock_stopwatch.split.side_effect = [
102+
ElapsedTime(nanoseconds=t) for t in elapsed_times
103+
]
104+
105+
monkeypatch.setattr(Timer, "_stopwatch", mock_stopwatch)
106+
yield
107+
108+
return patch
109+
110+
111+
# =========================================================================== #
112+
# Initiated Instances #
113+
# =========================================================================== #
114+
115+
116+
@fixture
117+
def stopwatch() -> Stopwatch:
118+
"""A newly created Stopwatch started at time ``0``."""
119+
watch: Stopwatch = Stopwatch()
120+
watch._start = 0
121+
return watch
122+
123+
124+
@fixture
125+
def timer() -> Timer:
126+
"""A newly created Timer with unlimited storage size."""
127+
return Timer()
128+
129+
130+
# =========================================================================== #
131+
# Elapsed Time #
132+
# =========================================================================== #
133+
134+
135+
@fixture
136+
def elapsed_1_ns() -> ElapsedTime:
137+
"""Elapsed Time of 1 nanosecond."""
138+
return ElapsedTime(nanoseconds=1)
139+
140+
141+
@fixture
142+
def elapsed_100_ns() -> ElapsedTime:
143+
"""Elapsed Time of 100 nanoseconds."""
144+
return ElapsedTime(nanoseconds=100)
145+
146+
147+
@fixture
148+
def elapsed_1_ms() -> ElapsedTime:
149+
"""Elapsed Time of 1 microsecond."""
150+
return ElapsedTime(nanoseconds=1000)
151+
152+
153+
@fixture
154+
def elapsed_1_pt_5_ms() -> ElapsedTime:
155+
"""Elapsed Time of 1.5 microseconds."""
156+
return ElapsedTime(nanoseconds=1500)
157+
158+
159+
@fixture
160+
def elapsed_1_sec() -> ElapsedTime:
161+
"""Elapsed Time of 1 second."""
162+
return ElapsedTime(nanoseconds=int(1e9))

0 commit comments

Comments
 (0)