A simpler way to handle timeouts in Python
Project description
EggTimer
There are some ubiquitous patterns that are elegant and simple. There are others that are not.
from time import time, sleep
start_time = time()
timeout_sec = 42.0
max_sleep_time_sec = 1.5
while time() - start_time < timeout_sec:
# Do or check some stuff
time_remaining = timeout_sec - (time() - start_time)
if time_remaining > 0:
sleep(min(time_remaining, max_sleep_time_sec))
else:
sleep(max_sleep_time_sec)
What is the purpose of this loop? Oh, I see, it's a timeout. Is the order of
operations correct in my loop condition? Have I correctly calculated
time_remaining
? Is my if
clause correct? Hint: It's not. Does this code
behave properly if the system clock is updated after I set start_time
? Hint:
It doesn't. How many times have I duplicated this code within my application?
We can do better. EggTimer can help.
from egg_timer import EggTimer
timer = EggTimer()
timer.set(42.0)
max_sleep_time_sec = 1.5
while not timer.is_expired():
# Do or check some stuff
sleep(min(timer.time_remaining_sec, max_sleep_time_sec))
Ah, that's better. Clear, concise, reusable, and expressive. The risk of defects is significantly lower, too!
Installation
Install with pip install -U egg-timer
Documentation
Python 3.10.4 (main, Jun 29 2022, 12:14:53) [GCC 11.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from egg_timer import EggTimer
>>> help(EggTimer)
Help on class EggTimer in module egg_timer.egg_timer:
class EggTimer(builtins.object)
| A class for checking whether or not a certain amount of time has elapsed.
|
| Methods defined here:
|
| __init__(self)
| Initialize self. See help(type(self)) for accurate signature.
|
| is_expired(self)
| Check whether or not the timer has expired
|
| :return: True if the elapsed time since set(TIMEOUT_SEC) was called is greater than
| TIMEOUT_SEC, False otherwise
|
| reset(self)
| Reset the timer without changing the timeout
|
| set(self, timeout_sec: float)
| Set a timer
|
| :param timeout_sec: A non-negative floating point number expressing the number of
| seconds to set the timeout for.
|
| ----------------------------------------------------------------------
| Readonly properties defined here:
|
| time_remaining_sec
| Return the amount of time remaining until the timer expires.
|
| :return: The number of seconds until the timer expires. If the timer is expired, this
| function returns 0 (it will never return a negative number).
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)
>>>
Running the tests
Running the tests is as simple as poetry install && poetry run pytest
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file egg_timer-1.1.0.tar.gz
.
File metadata
- Download URL: egg_timer-1.1.0.tar.gz
- Upload date:
- Size: 16.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.3.0 CPython/3.10.6 Linux/5.15.0-56-generic
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 7ec7c44196c3bc9cb1472cb37d96610ae3ec957e3af2961f6cb2f28ac019e78e |
|
MD5 | 27a9d69ac383ffc42b1f1846f028da23 |
|
BLAKE2b-256 | b1567e621c2c9fec400546cce61f5a62a827732fc75a7ecfdc147ba328349ae6 |
File details
Details for the file egg_timer-1.1.0-py3-none-any.whl
.
File metadata
- Download URL: egg_timer-1.1.0-py3-none-any.whl
- Upload date:
- Size: 16.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.3.0 CPython/3.10.6 Linux/5.15.0-56-generic
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 0be3105b04585cfff6f4a41b841866215b2ffe594b6e1b9c8bc781efb923e1a6 |
|
MD5 | 21b8f8f1704e7b12cd997d94b55d77c5 |
|
BLAKE2b-256 | 57ec6cf7739bcbce016da13d2d942bf93f72a1fdfc5fa1d9f7744bdc999855a1 |