feat: add Timer, a small context-manager/manual elapsed-time timer - #23
Conversation
Recovers work that had been stranded on the `audio_timestamp` branch since 2023 (that branch was merged once, via #19, then kept receiving commits that were never landed). Re-derived against current master and finished off. Changes from the stranded version: - `elapsed()` no longer detects "not started" by catching TypeError from `time() - None`. That conflated two different failures: if `egress` itself raised TypeError, the except block's `if start_time is None` was False, so the function fell off the end and returned None -- silently swallowing the real error. It now checks `start_time` explicitly and raises ValueError with an actionable message. - Uses `time.perf_counter` rather than `time.time`. Elapsed-time measurement wants a monotonic clock; wall-clock time can jump backwards under NTP adjustment and yield negative durations. Documented that this makes `start_time` a reference point, not a wall-clock timestamp. - Doctest sleeps reduced from 1s to 0.01s. The displayed outputs are unchanged (they were either +SKIP'd or floor-divided to 0), so this costs nothing in illustrative value and takes ~2s off the suite. Adds 9 unit tests, two of which are regression guards for the swallowed-error bug described above. Claude-Session: https://claude.ai/code/session_01EwmvrvgLNjzgE8weA4MMWU
|
CI cannot run on this repo — not a problem with this change.
So the branch cannot be gated on green CI, and I am not merging it on that basis. Unblocking this needs the wads uv-CI migration for |
* Migrate to pyproject.toml + the wads uv-CI stub The repo was still on setup.cfg/setup.py with a `runs-on: ubuntu-18.04` workflow — a runner label GitHub retired, so jobs queued forever and never ran. CI has effectively been dead here, which is why #23 could not be gated. - pyproject.toml (hatchling), version carried over at 1.0.42 to match PyPI; requires-python >=3.10 (3.8 is EOL and was the only version the old CI tested) - .github/workflows/ci.yml is now the 5-line reusable-workflow stub; all config lives in [tool.wads.ci.*] - testpaths points at the package, not a top-level tests/ — this repo's tests live in stream2py/tests/ and there are doctests in the modules - setup.cfg and setup.py removed - stream2py/utility/__init__.py gains the module docstring D100 wants 42 tests pass locally under the collection CI uses. * Use the named secrets transport in the stub The JSON transport (WADS_CI_SECRETS_JSON) is what ci-to-stub emits by default, but no repo in the fleet is on it yet and the run came back 'action_required' with zero jobs before anything executed. The named transport is what every already-migrated i2mint repo runs, so use the proven one here rather than debug a wads-side transport question inside a CI-revival PR. stream2py declares no env vars in [tool.wads.ci.env], so PYPI_PASSWORD (an i2mint org secret) is the only one that needs passing.
Summary
Adds
Timertostream2py.util(and exports it from the package root): a smallelapsed-time helper usable either as a context manager or started/stopped manually,
with an optional
egresscallable applied to the elapsed seconds.time.perf_counter), so it is unaffected by system clock adjustments.elapsed()on a stopped timer raises aValueErrorthat says what to do, ratherthan failing obscurely.
Changes
stream2py/util.py—Timer,identitystream2py/__init__.py— exportTimerstream2py/tests/test_util.py— testsBranch had been sitting unlanded since 2026-08-10; renamed from
claude/add-timerto
add-timerper the branch-naming policy.