You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
ScheduleEntry is defined in src/zae_limiter/schedule.py and listed in that module's own __all__, but it is not re-exported from src/zae_limiter/__init__.py. Neither the #222 core plan (14 tasks, all merged) nor the surface plan (12 tasks) adds it anywhere.
Every documented usage of the scheduled-limits feature begins with:
fromzae_limiterimportLimit, ScheduleEntry
which raises ImportError. The public surface the feature is documented against does not exist.
This is already failing CI and has been for some time.tests/doctest/test_docs_run.py executes every Python block under docs/. All six blocks in docs/guide/scheduled-limits.md failed β the first on the import itself, the rest on the resulting undefined name. That guide lives on PR #483, which is deliberately held until v0.14.0 ships, so the red was on a held branch and nobody chased it.
Found while fixing #524. The immediate red was worked around there by tagging the blocks .lint-only per the file's existing convention (7 passed / 14 skipped), which stops the guide failing CI but does not fix the export β a user copying those examples still gets ImportError.
Steps to Reproduce
uv run python -c "from zae_limiter import ScheduleEntry" β ImportError: cannot import name 'ScheduleEntry' from 'zae_limiter'
uv run pytest tests/doctest/test_docs_run.py -k scheduled-limits β every block in the guide fails
What to decide (not purely mechanical)
Which names belong at the package root. ScheduleEntry is required by every example and is the obvious yes. Also consider parse_cron, matches, effective_params, next_boundary, encode, decode, to_cron (and ParsedCron, also in schedule.__all__) β these are currently reachable only as zae_limiter.schedule.*. Most are internals that should stay that way, but the boundary should be chosen deliberately rather than by whichever name a doc example happened to need.
Constraint:schedule.py imports nothing from models.py, and that one-way dependency is load-bearing β it is what lets schedule.py be vendored into both Lambda packages. Re-exporting from __init__.py does not disturb it, but do not "tidy" the direction while in there.
Acceptance Criteria
from zae_limiter import ScheduleEntry succeeds; ScheduleEntry appears in src/zae_limiter/__init__.py's __all__
Any additional zae_limiter.schedule names the decision admits are likewise importable from the package root and listed in __init__.py's __all__
uv run pytest tests/doctest/test_docs_run.py -k scheduled-limits executes those blocks for real and passes (no skips for that file)
The public-surface decision β which schedule.py names are exported and which stay module-private β is recorded in CLAUDE.md (a Public API section; none exists today, so add one), naming the exported set explicitly
Release blocker for v0.14.0.
Description
ScheduleEntryis defined insrc/zae_limiter/schedule.pyand listed in that module's own__all__, but it is not re-exported fromsrc/zae_limiter/__init__.py. Neither the #222 core plan (14 tasks, all merged) nor the surface plan (12 tasks) adds it anywhere.Every documented usage of the scheduled-limits feature begins with:
which raises
ImportError. The public surface the feature is documented against does not exist.This is already failing CI and has been for some time.
tests/doctest/test_docs_run.pyexecutes every Python block underdocs/. All six blocks indocs/guide/scheduled-limits.mdfailed β the first on the import itself, the rest on the resulting undefined name. That guide lives on PR #483, which is deliberately held until v0.14.0 ships, so the red was on a held branch and nobody chased it.Found while fixing #524. The immediate red was worked around there by tagging the blocks
.lint-onlyper the file's existing convention (7 passed / 14 skipped), which stops the guide failing CI but does not fix the export β a user copying those examples still getsImportError.Steps to Reproduce
uv run python -c "from zae_limiter import ScheduleEntry"βImportError: cannot import name 'ScheduleEntry' from 'zae_limiter'docs/222-scheduled-limits-guide), revert the.lint-onlytags indocs/guide/scheduled-limits.mduv run pytest tests/doctest/test_docs_run.py -k scheduled-limitsβ every block in the guide failsWhat to decide (not purely mechanical)
Which names belong at the package root.
ScheduleEntryis required by every example and is the obvious yes. Also considerparse_cron,matches,effective_params,next_boundary,encode,decode,to_cron(andParsedCron, also inschedule.__all__) β these are currently reachable only aszae_limiter.schedule.*. Most are internals that should stay that way, but the boundary should be chosen deliberately rather than by whichever name a doc example happened to need.Constraint:
schedule.pyimports nothing frommodels.py, and that one-way dependency is load-bearing β it is what letsschedule.pybe vendored into both Lambda packages. Re-exporting from__init__.pydoes not disturb it, but do not "tidy" the direction while in there.Acceptance Criteria
from zae_limiter import ScheduleEntrysucceeds;ScheduleEntryappears insrc/zae_limiter/__init__.py's__all__zae_limiter.schedulenames the decision admits are likewise importable from the package root and listed in__init__.py's__all__.lint-onlytags added by π Calendar-reset guide predates ADR-137/138 and its main example is now invalidΒ #524's fix are removed fromdocs/guide/scheduled-limits.md(rg -c 'lint-only' docs/guide/scheduled-limits.mdreturns 0)uv run pytest tests/doctest/test_docs_run.py -k scheduled-limitsexecutes those blocks for real and passes (no skips for that file)schedule.pynames are exported and which stay module-private β is recorded inCLAUDE.md(a Public API section; none exists today, so add one), naming the exported set explicitlyDependencies
.lint-onlyremoval lands there or after it merges.