Skip to content

Allow 0 tokens in a CapacityLimiter instantiated outside an event loop - #1183

Merged
agronholm merged 2 commits into
agronholm:masterfrom
nyxst4ck:fix-capacity-limiter-adapter-zero-tokens
Jun 22, 2026
Merged

agronholm merged 2 commits into
agronholm:masterfrom
nyxst4ck:fix-capacity-limiter-adapter-zero-tokens

Conversation

@nyxst4ck

Copy link
Copy Markdown
Contributor

Changes

Fixes #.

PR #1019 (released in 4.12) allowed setting a CapacityLimiter's total tokens to 0, updating the docstring, the changelog and the asyncio backend setter (value < 1 → value < 0).

However, the CapacityLimiterAdapter.total_tokens setter in src/anyio/_core/_synchronization.py was missed and still enforced value < 1. This adapter is used whenever a CapacityLimiter is instantiated outside of a running event loop, so the documented 4.12 behavior was not honored on that path:

import anyio

anyio.CapacityLimiter(0)             # ValueError: total_tokens must be >= 1
limiter = anyio.CapacityLimiter(1)
limiter.total_tokens = 0             # ValueError: total_tokens must be >= 1

This aligns the adapter setter with the asyncio backend setter (value < 0, message "total_tokens must be >= 0") and adds a regression test for the outside-event-loop path.

Checklist

If this is a user-facing code change, like a bugfix or a new feature, please ensure that
you've fulfilled the following conditions (where applicable):

  • You've added tests (in tests/) which would fail without your patch
  • You've updated the documentation (in docs/), in case of behavior changes or new
    features
  • You've added a new changelog entry (in docs/versionhistory.rst).

If this is a trivial change, like a typo fix or a code reformatting, then you can ignore
these instructions.

Updating the changelog

If there are no entries after the last release, use **UNRELEASED** as the version.
If, say, your patch fixes issue #123, the entry should look like this:

- Fix big bad boo-boo in task groups
  (`#123 <https://github.com/agronholm/anyio/issues/123>`_; PR by @yourgithubaccount)

If there's no issue linked, just link to your pull request instead by updating the
changelog after you've created the PR.

nyxst4ck added 2 commits June 22, 2026 02:55
PR agronholm#1019 allowed setting a CapacityLimiter's total tokens to 0 (released in
4.12), updating both the docstring and the asyncio backend setter. However,
the CapacityLimiterAdapter.total_tokens setter - used whenever a
CapacityLimiter is instantiated outside of a running event loop - was missed
and still rejected 0 with "total_tokens must be >= 1".

This made CapacityLimiter(0) and limiter.total_tokens = 0 raise ValueError
when created outside an event loop, contradicting the documented behavior.

Align the adapter setter with the backend setter (value < 0) and add a
regression test covering the outside-event-loop path.

@agronholm agronholm left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thanks!

@agronholm
agronholm merged commit 3ceb6ff into agronholm:master Jun 22, 2026
19 checks passed
agronholm pushed a commit that referenced this pull request Aug 4, 2026
#1183)

PR #1019 allowed setting a CapacityLimiter's total tokens to 0 (released in 4.12), updating both the docstring and the asyncio backend setter. However, the CapacityLimiterAdapter.total_tokens setter - used whenever a CapacityLimiter is instantiated outside of a running event loop - was missed and still rejected 0 with "total_tokens must be >= 1".

This made CapacityLimiter(0) and limiter.total_tokens = 0 raise ValueError when created outside an event loop, contradicting the documented behavior.

Align the adapter setter with the backend setter (value < 0) and add a regression test covering the outside-event-loop path.
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.

2 participants