Install & Compatibility
Where this runs
tested against v5.12.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.95 runs
installs and imports cleanly · install 0.0s · import 0.250s · 33.9MB
glibcpy 3.10–3.95 runs
installs and imports cleanly · install 3.0s · import 0.214s · 34MB
30MB installed
● package 30MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
timing
✓ from tempora import timing
Module for measuring and profiling time.
schedule
✓ from tempora import schedule
Module for event scheduling.
utc
✓ from tempora import utc
Module for UTC datetime utilities.
timing.Stopwatch
✓ from tempora.timing import Stopwatch
schedule.Scheduler
✓ from tempora.schedule import Scheduler
utc.now
✓ from tempora.utc import now
Demonstrates basic usage of `tempora.timing.Stopwatch` for measuring execution time, `tempora.utc.now()` for getting current UTC time, and adding a simple task to `tempora.schedule.Scheduler`.
import datetime
from tempora.timing import Stopwatch
from tempora.schedule import Scheduler
from tempora.utc import now
# Example using Stopwatch
with Stopwatch() as sw:
sum(range(10000))
print(f"Summing range took: {sw.elapsed} seconds")
# Example using utc.now()
utc_time = now()
print(f"Current UTC time: {utc_time}")
# Example using Scheduler (basic usage - requires a running event loop)
def my_task():
print(f"Task executed at {now()}")
scheduler = Scheduler()
scheduler.add_event(my_task, datetime.timedelta(seconds=1))
print("Scheduler created to run a task after 1 second. (This example doesn't run the event loop).")
Debug
Known issues
gotchaWhen using testing libraries like `freezegun`, `tempora.utc.now()` might not reflect the 'frozen' time. This is because `freezegun` patches `datetime.datetime`, and if `tempora.utc.now()` or other `tempora` functions obtain a handle to `datetime.datetime` before `freezegun`'s context is entered, they will use the original, unfrozen time.fixEnsure `tempora` modules are reloaded or re-imported within the `freezegun` context, or mock `tempora.utc.now` directly.
affects: All versions where `freezegun` is used without explicit re-import or reload.
breakingThe library has moved away from `pytz` for timezone handling in favor of `zoneinfo` (standard library module from Python 3.9+). While `tempora` has ported this functionality, direct reliance on `pytz`-specific behaviors or imports like `pytz.UTC` might lead to incorrect results or deprecation warnings in other contexts. Always prefer `datetime.timezone.utc` or `zoneinfo.ZoneInfo` for modern Python development with time zones.fixMigrate your timezone handling code to use `datetime.timezone.utc` or `zoneinfo.ZoneInfo`. If compatibility with older Python versions (pre-3.9) is required, consider `backports.zoneinfo` or `python-dateutil` while being aware of their interaction with `tempora`.
affects: Users migrating from older systems or integrating with libraries still using `pytz` might be affected. Python 3.9+ is recommended for `zoneinfo` support.
gotchaThe `tempora.schedule.Scheduler` currently does not automatically run its event loop. To execute scheduled tasks, you need to explicitly run the scheduler's event loop, typically in a dedicated thread or by integrating it with an existing event loop (e.g., `asyncio`). The provided quickstart only sets up the schedule but does not run it.fixImplement a mechanism to run the scheduler's event loop, such as `scheduler.run_forever()` in a separate thread, or integrate it with your application's existing event loop.
affects: All versions up to 5.8.1
Upgrade
Version history
5.12.0latest on PyPI · released Jul 14, 2026
Audit
Dependencies
jaraco.collectionsrequiredUsed for various collection utilities.
jaraco.functoolsrequiredProvides additional functional programming tools.