agronholm-anyio-1218
When using AnyIO’s `CapacityLimiter` with the Trio backend, a non-blocking acquisition that cannot obtain a token raises Trio’s `WouldBlock` exception instead of AnyIO’s public `WouldBlock` exception.
This affects both acquiring on behalf of the current task and acquiring on behalf of an explicitly supplied borrower. For example, after a limiter with capacity one has already been acquired, a second call to either non-blocking acquisition method fails with the wrong exception type. Users should consistently receive `anyio.WouldBlock`, regardless of the backend used.
Hidden tests · 2 fail-to-pass, 251 pass-to-passrun after the agent submits, in a clean verifier
Test patch · 25 lines
diff --git a/tests/test_synchronization.py b/tests/test_synchronization.py
index 0158fcd4b..98f2357c0 100644
--- a/tests/test_synchronization.py
+++ b/tests/test_synchronization.py
@@ -976,3 +976,20 @@ async def borrower(
tg.cancel_scope.cancel()
pytest.fail("The second borrower failed to acquire the limiter")
+
+ async def test_acquire_nowait(self) -> None:
+ async def borrower() -> None:
+ limiter.acquire_nowait()
+
+ limiter = CapacityLimiter(1)
+ limiter.acquire_nowait()
+ with pytest.RaisesGroup(pytest.RaisesExc(WouldBlock)):
+ async with create_task_group() as tg:
+ tg.start_soon(borrower)
+
+ async def test_acquire_on_behalf_of_nowait(self) -> None:
+ borrower1, borrower2 = object(), object()
+ limiter = CapacityLimiter(1)
+ limiter.acquire_on_behalf_of_nowait(borrower1)
+ with pytest.raises(WouldBlock):
+ limiter.acquire_on_behalf_of_nowait(borrower2)
Reference fix · 2 files, +12 −2the upstream merge, used only for grading calibration
The agent could not see this: the repository holds one commit and the sandbox has no network. Leak audit.
docs/versionhistory.rst, src/anyio/_backends/_trio.py
diff --git a/docs/versionhistory.rst b/docs/versionhistory.rst
index 8167d3aa9..98bbb70a1 100644
--- a/docs/versionhistory.rst
+++ b/docs/versionhistory.rst
@@ -23,6 +23,10 @@ This library adheres to `Semantic Versioning 2.0 <http://semver.org/>`_.
- Fixed ``anyio.open_process()`` (and ``run_process()``) ignoring the ``extra_groups``
argument, as it mistakenly passed the value of the ``group`` argument instead
(`#1209 <https://github.com/agronholm/anyio/pull/1209>`_)
+- Fixed ``CapacityLimiter.acquire_nowait()`` and
+ ``CapacityLimiter.acquire_nowait_on_behalf_of()`` raising ``trio.WouldBlock`` instead
+ of ``anyio.WouldBlock`` on the ``trio`` backend when there are no tokens available
+ (`#1218 <https://github.com/agronholm/anyio/pull/1218>`_)
**4.14.1**
diff --git a/src/anyio/_backends/_trio.py b/src/anyio/_backends/_trio.py
index 341ddea19..43d24d233 100644
--- a/src/anyio/_backends/_trio.py
+++ b/src/anyio/_backends/_trio.py
@@ -888,10 +888,16 @@ def available_tokens(self) -> float:
return self.__original.available_tokens
def acquire_nowait(self) -> None:
- self.__original.acquire_nowait()
+ try:
+ self.__original.acquire_nowait()
+ except trio.WouldBlock:
+ raise WouldBlock from None
def acquire_on_behalf_of_nowait(self, borrower: object) -> None:
- self.__original.acquire_on_behalf_of_nowait(borrower)
+ try:
+ self.__original.acquire_on_behalf_of_nowait(borrower)
+ except trio.WouldBlock:
+ raise WouldBlock from None
async def acquire(self) -> None:
await self.__original.acquire()
GLM-5.3 Flash · attempt 2 · solved · 6 steps · $0.001
Submitted diff · 23 lines
diff --git a/src/anyio/_backends/_trio.py b/src/anyio/_backends/_trio.py
index 341ddea..43d24d2 100644
--- a/src/anyio/_backends/_trio.py
+++ b/src/anyio/_backends/_trio.py
@@ -888,10 +888,16 @@ class CapacityLimiter(BaseCapacityLimiter):
return self.__original.available_tokens
def acquire_nowait(self) -> None:
- self.__original.acquire_nowait()
+ try:
+ self.__original.acquire_nowait()
+ except trio.WouldBlock:
+ raise WouldBlock from None
def acquire_on_behalf_of_nowait(self, borrower: object) -> None:
- self.__original.acquire_on_behalf_of_nowait(borrower)
+ try:
+ self.__original.acquire_on_behalf_of_nowait(borrower)
+ except trio.WouldBlock:
+ raise WouldBlock from None
async def acquire(self) -> None:
await self.__original.acquire()$ grep -rn "WouldBlock" /repo/src/anyio/_backends/_trio.py | head -30; grep -n "acquire_nowait\|acquire_on_behalf_of_nowait" /repo/src/anyio/_backends/_trio.py
output · 17 lines
61: WouldBlock, 755: except trio.WouldBlock: 764: except trio.WouldBlock: 765: raise WouldBlock from None 815: except trio.WouldBlock: 821: except trio.WouldBlock: 822: raise WouldBlock from None 754: self.__original.acquire_nowait() 761: def acquire_nowait(self) -> None: 763: self.__original.acquire_nowait() 814: self.__original.acquire_nowait() 818: def acquire_nowait(self) -> None:
5 more lines
820: self.__original.acquire_nowait() 890: def acquire_nowait(self) -> None: 891: self.__original.acquire_nowait() 893: def acquire_on_behalf_of_nowait(self, borrower: object) -> None: 894: self.__original.acquire_on_behalf_of_nowait(borrower)
$ sed -n 870,905p /repo/src/anyio/_backends/_trio.py
output · 36 lines
exc_tb: TracebackType | None,
) -> None:
await self.__original.__aexit__(exc_type, exc_val, exc_tb)
@property
def total_tokens(self) -> float:
return self.__original.total_tokens
@total_tokens.setter
def total_tokens(self, value: float) -> None:
self.__original.total_tokens = value
24 more lines
@property
def borrowed_tokens(self) -> int:
return self.__original.borrowed_tokens
@property
def available_tokens(self) -> float:
return self.__original.available_tokens
def acquire_nowait(self) -> None:
self.__original.acquire_nowait()
def acquire_on_behalf_of_nowait(self, borrower: object) -> None:
self.__original.acquire_on_behalf_of_nowait(borrower)
async def acquire(self) -> None:
await self.__original.acquire()
async def acquire_on_behalf_of(self, borrower: object) -> None:
await self.__original.acquire_on_behalf_of(borrower)
def release(self) -> None:
return self.__original.release()
def release_on_behalf_of(self, borrower: object) -> None:$ cd /repo && python - <<'PY'
output · 2 lines
(<class 'RuntimeError'>, <class 'Exception'>, <class 'BaseException'>) (<class 'trio.WouldBlock'>, <class 'Exception'>, <class 'BaseException'>)
$ cd /repo && python - <<'PY'
output · 24 lines
Traceback (most recent call last):
File "<stdin>", line 10, in <module>
File "/repo/src/anyio/_core/_eventloop.py", line 83, in run
return async_backend.run(func, args, {}, backend_options)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/repo/src/anyio/_backends/_trio.py", line 1087, in run
return trio.run(ensure_returns_coro(func), *args, **options)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/trio/_core/_run.py", line 2543, in run
raise runner.main_task_outcome.error
File "<stdin>", line 7, in main
File "<stdin>", line 5, in <lambda>12 more lines
File "/repo/src/anyio/_backends/_trio.py", line 892, in acquire_nowait
self.__original.acquire_nowait()
File "/usr/local/lib/python3.12/site-packages/trio/_sync.py", line 290, in acquire_nowait
self.acquire_on_behalf_of_nowait(trio.
…[14 chars omitted]…
nt_task())
File "/usr/local/lib/python3.12/site-packages/trio/_sync.py", line 312, in acquire_on_behalf_of_nowait
raise RuntimeError(
RuntimeError: this borrower is already holding one of this CapacityLimiter's tokens
........................................................................ [ 88%]
............................. [100%]
245 passed in 23.72s$ cd /repo && python - <<'PY'
output · 2 lines
ok anyio.WouldBlock ok anyio.WouldBlock
Fixed and tests pass (245 passed).
$ done: {"notes": "Wrapped trio.WouldBlock in CapacityLimiter.acquire_nowait and acquire_on_behalf_of_nowait in the Trio backend to raise anyio.WouldBlock."}output · 1 lines
submitted.
GLM-5.3 Flash · attempt 3 · solved · 6 steps · $0.001
Submitted diff · 23 lines
diff --git a/src/anyio/_backends/_trio.py b/src/anyio/_backends/_trio.py
index 341ddea..43d24d2 100644
--- a/src/anyio/_backends/_trio.py
+++ b/src/anyio/_backends/_trio.py
@@ -888,10 +888,16 @@ class CapacityLimiter(BaseCapacityLimiter):
return self.__original.available_tokens
def acquire_nowait(self) -> None:
- self.__original.acquire_nowait()
+ try:
+ self.__original.acquire_nowait()
+ except trio.WouldBlock:
+ raise WouldBlock from None
def acquire_on_behalf_of_nowait(self, borrower: object) -> None:
- self.__original.acquire_on_behalf_of_nowait(borrower)
+ try:
+ self.__original.acquire_on_behalf_of_nowait(borrower)
+ except trio.WouldBlock:
+ raise WouldBlock from None
async def acquire(self) -> None:
await self.__original.acquire()$ grep -rn "WouldBlock" /repo/src/anyio/_backends/_trio.py | head -30; grep -n "acquire_nowait\|_notify_borrower\|borrower" /repo/src/anyio/_backends/_trio.py | head -40
output · 22 lines
61: WouldBlock, 755: except trio.WouldBlock: 764: except trio.WouldBlock: 765: raise WouldBlock from None 815: except trio.WouldBlock: 821: except trio.WouldBlock: 822: raise WouldBlock from None 754: self.__original.acquire_nowait() 761: def acquire_nowait(self) -> None: 763: self.__original.acquire_nowait() 814: self.__original.acquire_nowait() 818: def acquire_nowait(self) -> None:
10 more lines
820: self.__original.acquire_nowait() 890: def acquire_nowait(self) -> None: 891: self.__original.acquire_nowait() 893: def acquire_on_behalf_of_nowait(self, borrower: object) -> None: 894: self.__original.acquire_on_behalf_of_nowait(borrower) 899: async def acquire_on_behalf_of(self, borrower: object) -> None: 900: await self.__original.acquire_on_behalf_of(borrower) 905: def release_on_behalf_of(self, borrower: object) -> None: 906: return self.__original.release_on_behalf_of(borrower) 913: borrowers=tuple(orig.borrowers),
$ sed -n 880,910p /repo/src/anyio/_backends/_trio.py
output · 31 lines
self.__original.total_tokens = value
@property
def borrowed_tokens(self) -> int:
return self.__original.borrowed_tokens
@property
def available_tokens(self) -> float:
return self.__original.available_tokens
def acquire_nowait(self) -> None:
self.__original.acquire_nowait()19 more lines
def acquire_on_behalf_of_nowait(self, borrower: object) -> None:
self.__original.acquire_on_behalf_of_nowait(borrower)
async def acquire(self) -> None:
await self.__original.acquire()
async def acquire_on_behalf_of(self, borrower: object) -> None:
await self.__original.acquire_on_behalf_of(borrower)
def release(self) -> None:
return self.__original.release()
def release_on_behalf_of(self, borrower: object) -> None:
return self.__original.release_on_behalf_of(borrower)
def statistics(self) -> CapacityLimiterStatistics:
orig = self.__original.statistics()
return CapacityLimiterStatistics($ python - <<'PY'
output · 12 lines
Traceback (most recent call last):
File "<stdin>", line 13, in <module>
File "/usr/local/lib/python3.12/site-packages/trio/_core/_run.py", line 2543, in run
raise runner.main_task_outcome.error
File "<stdin>", line 6, in main
File "/repo/src/anyio/_backends/_trio.py", line 892, in acquire_nowait
self.__original.acquire_nowait()
File "/usr/local/lib/python3.12/site-packages/trio/_sync.py", line 290, in acquire_nowait
self.acquire_on_behalf_of_nowait(trio.lowlevel.current_task())
File "/usr/local/lib/python3.12/site-packages/trio/_sync.py", line 312, in acquire_on_behalf_of_nowait
raise RuntimeError(
RuntimeError: this borrower is already holding one of this CapacityLimiter's tokens$ python - <<'PY'
output · 15 lines
Traceback (most recent call last):
File "<stdin>", line 13, in <module>
File "/usr/local/lib/python3.12/site-packages/trio/_core/_run.py", line 2543, in run
raise runner.main_task_outcome.error
File "<stdin>", line 6, in main
File "/repo/src/anyio/_backends/_trio.py", line 892, in acquire_nowait
self.__original.acquire_nowait()
File "/usr/local/lib/python3.12/site-packages/trio/_sync.py", line 290, in acquire_nowait
self.acquire_on_behalf_of_nowait(trio.lowlevel.current_task())
File "/usr/local/lib/python3.12/site-packages/trio/_sync.py", line 312, in acquire_on_behalf_of_nowait
raise RuntimeError(
RuntimeError: this borrower is already holding one of this CapacityLimiter's tokens3 more lines
........................................................................ [ 88%] ............................. [100%] 245 passed in 23.68s
$ python - <<'PY'
output · 2 lines
ok1 ok2
Fix works and all 245 synchronization tests pass.
$ done: {"notes": "Wrapped CapacityLimiter.acquire_nowait and acquire_on_behalf_of_nowait in the Trio backend to translate trio.WouldBlock into anyio.WouldBlock."}output · 1 lines
submitted.
GLM-5.3 Flash · attempt 4 · solved · 9 steps · $0.001
Submitted diff · 23 lines
diff --git a/src/anyio/_backends/_trio.py b/src/anyio/_backends/_trio.py
index 341ddea..43d24d2 100644
--- a/src/anyio/_backends/_trio.py
+++ b/src/anyio/_backends/_trio.py
@@ -888,10 +888,16 @@ class CapacityLimiter(BaseCapacityLimiter):
return self.__original.available_tokens
def acquire_nowait(self) -> None:
- self.__original.acquire_nowait()
+ try:
+ self.__original.acquire_nowait()
+ except trio.WouldBlock:
+ raise WouldBlock from None
def acquire_on_behalf_of_nowait(self, borrower: object) -> None:
- self.__original.acquire_on_behalf_of_nowait(borrower)
+ try:
+ self.__original.acquire_on_behalf_of_nowait(borrower)
+ except trio.WouldBlock:
+ raise WouldBlock from None
async def acquire(self) -> None:
await self.__original.acquire()$ grep -rn "WouldBlock" /repo/src/anyio/_backends/_trio.py | head -30
output · 7 lines
61: WouldBlock, 755: except trio.WouldBlock: 764: except trio.WouldBlock: 765: raise WouldBlock from None 815: except trio.WouldBlock: 821: except trio.WouldBlock: 822: raise WouldBlock from None
$ sed -n 740,830p /repo/src/anyio/_backends/_trio.py
output · 45 lines
async def acquire(self) -> None:
if not self._fast_acquire:
try:
await self.__original.acquire()
except RuntimeError as exc:
self._convert_runtime_error_msg(exc)
raise
return
# This is the "fast path" where we don't let other tasks run
await trio.lowlevel.checkpoint_if_cancelled()33 more lines
try:
self.__original.acquire_nowait()
except trio.WouldBlock:
await self.__original._lot.park()
except RuntimeError as exc:
self._convert_runtime_error_msg(exc)
raise
def acquire_nowait(self) -> None:
try:
self.__original.acquire_nowait()
except trio.WouldBlock:
raise WouldBlock from None
except RuntimeError as exc:
self._convert_runtime_error_msg(exc)
…[1373 chars omitted]…
rio.WouldBlock:
await self.__original._lot.park()
def acquire_nowait(self) -> None:
try:
self.__original.acquire_nowait()
except trio.WouldBlock:
raise WouldBlock from None
@property
def max_value(self) -> int | None:
return self.__original.max_value
@property
def value(self) -> int:
return self.__original.value$ grep -n "class CapacityLimiter" -A 80 /repo/src/anyio/_backends/_trio.py | sed -n 1,120p
output · 42 lines
840:class CapacityLimiter(BaseCapacityLimiter):
841- __slots__ = ("__original",)
842-
843- def __new__(
844- cls,
845- total_tokens: float | None = None,
846- *,
847- original: trio.CapacityLimiter | None = None,
848- ) -> CapacityLimiter:
849- return object.__new__(cls)
850-
851- def __init__(30 more lines
852- self,
853- total_tokens: float | None = None,
854- *,
855- original: trio.CapacityLimiter | None = None,
856- ) -> None:
857- if original is not None:
858- self.__original = original
859- else:
860- assert total_tokens is not None
861- self.__original = trio.CapacityLimiter(total_tokens)
862-
863- async def __aenter__(self) -> None:
864- return await self.__original.__aenter__()
865-
866- async def __aexit__(
867- self,
868- exc_type: type[
…[1451 chars omitted]…
ig = self.__original.statistics()
910- return CapacityLimiterStatistics(
911- borrowed_tokens=orig.borrowed_tokens,
912- total_tokens=orig.total_tokens,
913- borrowers=tuple(orig.borrowers),
914- tasks_waiting=orig.tasks_waiting,
915- )
916-
917-
918-_capacity_limiter_wrapper: trio.lowlevel.RunVar = RunVar("_capacity_limiter_wrapper")
919-
920-$ cd /repo && python - <<'PY'
output · 1 lines
(<class 'RuntimeError'>, <class 'Exception'>, <class 'BaseException'>)
$ cd /repo && python - <<'PY'
output · 2 lines
<class 'RuntimeError'> <class 'anyio.WouldBlock'>
$ cd /repo && python - <<'PY'
output · 8 lines
0.34.0
RuntimeError("this borrower is already holding one of this CapacityLimiter's tokens")
18: WouldBlock,
98: pytest.raises(WouldBlock, lock.acquire_nowait)
389: pytest.raises(WouldBlock, condition.acquire_nowait)
562: pytest.raises(WouldBlock, semaphore.acquire_nowait)
624: WouldBlock.
633: pytest.raises(WouldBlock, semaphore.acquire_nowait)$ cd /repo && python - <<'PY'
output · 5 lines
<class 'anyio.WouldBlock'> <class 'anyio.WouldBlock'> ........................................................................ [ 88%] ............................. [100%] 245 passed in 28.87s
$ cd /repo && git diff && python -m pytest tests/test_synchronization.py tests/streams -q 2>&1 | tail -2
output · 25 lines
diff --git a/src/anyio/_backends/_trio.py b/src/anyio/_backends/_trio.py
index 341ddea..43d24d2 100644
--- a/src/anyio/_backends/_trio.py
+++ b/src/anyio/_backends/_trio.py
@@ -888,10 +888,16 @@ class CapacityLimiter(BaseCapacityLimiter):
return self.__original.available_tokens
def acquire_nowait(self) -> None:
- self.__original.acquire_nowait()
+ try:
+ self.__original.acquire_nowait()
+ except trio.WouldBlock:13 more lines
+ raise WouldBlock from None
def acquire_on_behalf_of_nowait(self, borrower: object) -> None:
- self.__original.acquire_on_behalf_of_nowait(borrower)
+ try:
+ self.__original.acquire_on_behalf_of_nowait(borrower)
+ except trio.WouldBlock:
+ raise WouldBlock from None
async def acquire(self) -> None:
await self.__original.acquire()
...... [100%]
582 passed in 66.38s (0:01:06)$ done: {"notes": "Trio backend CapacityLimiter.acquire_nowait / acquire_on_behalf_of_nowait now convert trio.WouldBlock into anyio.WouldBlock. All tests pass."}output · 1 lines
submitted.
GLM-5.3 Flash · attempt 5 · solved · 7 steps · $0.001
Submitted diff · 23 lines
diff --git a/src/anyio/_backends/_trio.py b/src/anyio/_backends/_trio.py
index 341ddea..43d24d2 100644
--- a/src/anyio/_backends/_trio.py
+++ b/src/anyio/_backends/_trio.py
@@ -888,10 +888,16 @@ class CapacityLimiter(BaseCapacityLimiter):
return self.__original.available_tokens
def acquire_nowait(self) -> None:
- self.__original.acquire_nowait()
+ try:
+ self.__original.acquire_nowait()
+ except trio.WouldBlock:
+ raise WouldBlock from None
def acquire_on_behalf_of_nowait(self, borrower: object) -> None:
- self.__original.acquire_on_behalf_of_nowait(borrower)
+ try:
+ self.__original.acquire_on_behalf_of_nowait(borrower)
+ except trio.WouldBlock:
+ raise WouldBlock from None
async def acquire(self) -> None:
await self.__original.acquire()$ ls /repo; grep -rn "WouldBlock" /repo/src/anyio/_backends/_trio.py | head -30
output · 15 lines
AGENTS.md CLAUDE.md LICENSE README.rst docs pyproject.toml src tests 61: WouldBlock, 755: except trio.WouldBlock: 764: except trio.WouldBlock: 765: raise WouldBlock from None
3 more lines
815: except trio.WouldBlock: 821: except trio.WouldBlock: 822: raise WouldBlock from None
$ sed -n 740,830p /repo/src/anyio/_backends/_trio.py
output · 45 lines
async def acquire(self) -> None:
if not self._fast_acquire:
try:
await self.__original.acquire()
except RuntimeError as exc:
self._convert_runtime_error_msg(exc)
raise
return
# This is the "fast path" where we don't let other tasks run
await trio.lowlevel.checkpoint_if_cancelled()33 more lines
try:
self.__original.acquire_nowait()
except trio.WouldBlock:
await self.__original._lot.park()
except RuntimeError as exc:
self._convert_runtime_error_msg(exc)
raise
def acquire_nowait(self) -> None:
try:
self.__original.acquire_nowait()
except trio.WouldBlock:
raise WouldBlock from None
except RuntimeError as exc:
self._convert_runtime_error_msg(exc)
…[1373 chars omitted]…
rio.WouldBlock:
await self.__original._lot.park()
def acquire_nowait(self) -> None:
try:
self.__original.acquire_nowait()
except trio.WouldBlock:
raise WouldBlock from None
@property
def max_value(self) -> int | None:
return self.__original.max_value
@property
def value(self) -> int:
return self.__original.value$ grep -n "class CapacityLimiter" -A 80 /repo/src/anyio/_backends/_trio.py | grep -n "acquire_nowait\|acquire_on_behalf\|WouldBlock\|def "
output · 18 lines
4:843- def __new__( 12:851- def __init__( 24:863- async def __aenter__(self) -> None: 27:866- async def __aexit__( 36:875- def total_tokens(self) -> float: 40:879- def total_tokens(self, value: float) -> None: 44:883- def borrowed_tokens(self) -> int: 48:887- def available_tokens(self) -> float: 51:890- def acquire_nowait(self) -> None: 52:891- self.__original.acquire_nowait() 54:893- def acquire_on_behalf_of_nowait(self, borrower: object) -> None: 55:894- self.__original.acquire_on_behalf_of_nowait(borrower)
6 more lines
57:896- async def acquire(self) -> None: 60:899- async def acquire_on_behalf_of(self, borrower: object) -> None: 61:900- await self.__original.acquire_on_behalf_of(borrower) 63:902- def release(self) -> None: 66:905- def release_on_behalf_of(self, borrower: object) -> None: 69:908- def statistics(self) -> CapacityLimiterStatistics:
$ cd /repo && python - <<'PY'
output · 18 lines
Traceback (most recent call last):
File "<stdin>", line 10, in <module>
File "/repo/src/anyio/_core/_eventloop.py", line 83, in run
return async_backend.run(func, args, {}, backend_options)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/repo/src/anyio/_backends/_trio.py", line 1087, in run
return trio.run(ensure_returns_coro(func), *args, **options)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/trio/_core/_run.py", line 2543, in run
raise runner.main_task_outcome.error
File "<stdin>", line 7, in main
File "/repo/src/anyio/_backends/_trio.py", line 892, in acquire_nowait6 more lines
self.__original.acquire_nowait()
File "/usr/local/lib/python3.12/site-packages/trio/_sync.py", line 290, in acquire_nowait
self.acquire_on_behalf_of_nowait(trio.lowlevel.current_task())
File "/usr/local/lib/python3.12/site-packages/trio/_sync.py", line 312, in acquire_on_behalf_of_nowait
raise RuntimeError(
RuntimeError: this borrower is already holding one of this CapacityLimiter's tokens$ cd /repo && python - <<'PY'
output · 21 lines
Traceback (most recent call last):
File "<stdin>", line 10, in <module>
File "/repo/src/anyio/_core/_eventloop.py", line 83, in run
return async_backend.run(func, args, {}, backend_options)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/repo/src/anyio/_backends/_trio.py", line 1087, in run
return trio.run(ensure_returns_coro(func), *args, **options)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/trio/_core/_run.py", line 2543, in run
raise runner.main_task_outcome.error
File "<stdin>", line 7, in main
File "/repo/src/anyio/_backends/_trio.py", line 892, in acquire_nowait9 more lines
self.__original.acquire_nowait()
File "/usr/local/lib/python3.12/site-packages/trio/_sync.py", line 290, in acquire_nowait
self.acquire_on_behalf_of_nowait(trio.lowlevel.current_task())
File "/usr/local/lib/python3.12/site-packages/trio/_sync.py", line 312, in acquire_on_behalf_of_nowait
raise RuntimeError(
RuntimeError: this borrower is already holding one of this CapacityLimiter's tokens
........................................................................ [ 88%]
............................. [100%]
245 passed in 24.49s$ cd /repo && python - <<'PY'
output · 2 lines
ok ok
$ done: {"notes": "Wrapped trio CapacityLimiter.acquire_nowait / acquire_on_behalf_of_nowait to convert trio.WouldBlock into anyio.WouldBlock. Reproducer passes; tests/test_synchronization.py 245 passed."}output · 1 lines
submitted.