Skip to content

feat: bilingual docs, GitHub Pages deployment, and concurrency bug fixes#4

Merged
jrfk merged 2 commits into
mainfrom
feat/async-value-library
Jul 3, 2026
Merged

feat: bilingual docs, GitHub Pages deployment, and concurrency bug fixes#4
jrfk merged 2 commits into
mainfrom
feat/async-value-library

Conversation

@jrfk

@jrfk jrfk commented Jul 2, 2026

Copy link
Copy Markdown
Owner

Summary

Completes the library for public consumption: comprehensive bilingual documentation deployed to GitHub Pages, plus fixes for eight real concurrency bugs found during review — each verified by a repro and covered by regression tests (suite grows 69 → 92 tests).

Documentation (English / 日本語)

  • MkDocs Material + mkdocs-static-i18n + mkdocstrings, covering the full public API:
    • Guides: waiting for values, iterating over changes, deriving & composing, tasks & cancellation, events/streams/timing — all fully bilingual (*.md / *.ja.md).
    • API reference generated from docstrings (added docstrings + type annotations to all AsyncValue methods).
  • GitHub Pages deployment workflow (docs.yml); Pages is already enabled with the 'GitHub Actions' source → deploys on merge to https://jrfk.github.io/asyncio-util/ (ja: /ja/).
  • Bilingual READMEs, CHANGELOG.md, runnable examples/, strict docs build in CI.

Bug fixes (all with regression tests)

Bug Symptom
wait_value(held_for=) raised TimeoutError when the condition successfully held
eventual_values(held_for=) hold logic inverted + unhandled TimeoutError to the consumer
raising predicates crashed the assigning task and starved every later waiter; now delivered to their own waiter only
compose_values() _transform_ exceptions silently swallowed → output frozen at last good value
move_on_when() leaked CancelledError (body never ran) when the trigger completed without awaiting, e.g. an already-set event; trigger exceptions were swallowed
run_and_cancelling() / start_and_cancelling() background failure masked the body's own exception
wait_any() / wait_all() / wait_any_map() leaked already-started tasks when a later callable raised synchronously
MulticastQueue broadcasting a legitimate None terminated listeners (sentinel collision)
periodic() cumulative drift; now anchored to the absolute start + k*period grid

Housekeeping

  • requires-python >= 3.10 (3.8/3.9 are EOL); CI matrix 3.10–3.14 + docs build job.
  • py.typed, project metadata (description, keywords, classifiers, Pages URL), pytest asyncio_mode=auto, version 0.1.0.

Test plan

  • uv run pytest — 92 tests pass (69 existing + 23 new regression tests)
  • uv run mkdocs build --strict — clean, en + ja both built
  • All three examples/*.py run with expected output
  • uv build — wheel includes py.typed
  • After merge: docs workflow deploys to https://jrfk.github.io/asyncio-util/

Documentation (English / 日本語):
- MkDocs Material + mkdocs-static-i18n + mkdocstrings covering the full
  public API: guides for waiting, iterating, deriving/composing,
  tasks/cancellation, and events/streams, plus an API reference.
- Docstrings and type annotations for all AsyncValue methods.
- GitHub Pages deployment workflow (docs.yml) and a strict docs build
  job in CI; bilingual READMEs; CHANGELOG; runnable examples/.

Bug fixes (each with regression tests; suite grows 69 -> 92):
- wait_value(held_for=) raised TimeoutError on a successful hold;
  eventual_values(held_for=) had the hold logic inverted.
- Raising predicates crashed the assigning task and starved other
  waiters; they are now delivered to their own waiter only.
- compose_values() silently swallowed _transform_ exceptions, freezing
  the output at its last good value.
- move_on_when() leaked CancelledError when the trigger completed
  without awaiting, and swallowed trigger exceptions.
- run_and_cancelling()/start_and_cancelling() masked body exceptions
  with background-task failures.
- wait_any()/wait_all()/wait_any_map() leaked started tasks when a
  later callable raised synchronously.
- MulticastQueue ended streams on a legitimate None broadcast.
- periodic() drifted; now anchored to the absolute start+k*period grid.

Housekeeping: requires-python >=3.10, CI matrix 3.10-3.14, py.typed,
project metadata/URLs, pytest asyncio_mode=auto, version 0.1.0.
@jrfk jrfk force-pushed the feat/async-value-library branch from 65a7b57 to d2ea585 Compare July 2, 2026 16:05
@jrfk jrfk changed the title feat: implement AsyncValue library with bilingual docs and CI feat: bilingual docs, GitHub Pages deployment, and concurrency bug fixes Jul 2, 2026
Found while auditing merged PRs #1-#3: get() raises StopAsyncIteration
once the listen() context has exited, which was undocumented.
@jrfk jrfk merged commit 0292198 into main Jul 3, 2026
6 checks passed
@jrfk jrfk deleted the feat/async-value-library branch July 3, 2026 15:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant