Bardic v0.9.2: Scoping and Python Versions
A polish and compatibility release, with two insidious bug fixes.
Bug Fixes
@py: Block Functions Invisible to Comprehensions on Python <3.12
Functions defined inside @py: blocks couldn't be seen by dict/list/set comprehensions on Python 3.10–3.11 due to comprehension scoping rules. The comprehension gets its own scope, and functions defined via exec() with separate globals/locals weren't visible across that boundary.
In practice: code that worked fine on 3.12 would throw a silent NameError on 3.10 or 3.11. Fixed by using a single unified namespace for exec().
If you test on 3.12 but deploy on 3.10, this one was waiting for you.
Passage Parameters and _state/_local Not Accessible in @py: Blocks
@py: blocks were building their execution context separately from ~ statements. This meant passage parameters (values passed into a passage via -> PassageName(param=value)) and the _state/_local special variables were only available in ~ lines — not in @py: blocks, where you actually want to use them.
:: Reading(client=None)
@py:
# This used to fail silently — client was undefined here
trust_bonus = 10 if client.is_returning else 0
reader_empathy += trust_bonus
@endpy
Fixed. Passage parameters are now consistently available in both ~ statements and @py: blocks, and are properly scoped so they don't leak into global state. (Fixes #5)
Other Additions
Inline image syntax:  now renders as <img> in browser bundles. Terminal player shows [Image: alt text].
Pre-commit hooks: ruff lint/format, trailing whitespace, end-of-file fixer, YAML/JSON validation, large file check.
pre-commit installInfrastructure
- Python 3.13 support: added to CI matrix and PyPI classifiers
- CI now tests 3.10, 3.11, 3.12, 3.13 with
fail-fast: false: the@py:scoping fix above is why this matters - CI lint job: ruff check + format verification runs before tests
- GitHub Actions updated to checkout@v4 and setup-python@v5
- Codebase formatted with ruff: consistent style throughout
Upgrade Notes
pip install --upgrade bardicNo story file changes needed. If you have @py: blocks that use passage parameters or _state/_local, they'll now work as expected — no changes required on your end.