Skip to content

Commit 2b09585

Browse files
gschaffneragronholm
andcommitted
Fix memory streams incorrectly raising cancelled when *_nowait() is called immediately after cancelling send()/receive()
This partially reverts commit 6b0a1f3. Co-authored-by: Alex Grönholm <[email protected]>
1 parent 685d35b commit 2b09585

File tree

2 files changed

+26
-0
lines changed

2 files changed

+26
-0
lines changed

Diff for: docs/versionhistory.rst

+14
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,20 @@ This library adheres to `Semantic Versioning 2.0 <http://semver.org/>`_.
2828
- Emit a ``ResourceWarning`` for ``MemoryObjectReceiveStream`` and
2929
``MemoryObjectSendStream`` that were garbage collected without being closed (PR by
3030
Andrey Kazantcev)
31+
- Fixed memory object stream operations incorrectly raising cancelled under certain
32+
conditions where it is too late to do so:
33+
34+
- Fixed memory object streams dropping items when
35+
``MemoryObjectSendStream.send_nowait()`` was called immediately after cancelling the
36+
scope of an ``await MemoryObjectReceiveStream.receive()`` call (`#728
37+
<https://github.com/agronholm/anyio/issues/728>`_)
38+
39+
- Fixed ``MemoryObjectSendStream.send()`` raising cancelled despite succeeding when
40+
``MemoryObjectReceiveStream.receive_nowait()`` is called immediately after
41+
cancelling the scope of the ``MemoryObjectSendStream.send()`` call (`#729
42+
<https://github.com/agronholm/anyio/issues/729>`_)
43+
44+
(PR by Ganden Schaffner)
3145

3246
**4.3.0**
3347

Diff for: src/anyio/streams/memory.py

+12
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
ClosedResourceError,
1212
EndOfStream,
1313
WouldBlock,
14+
get_cancelled_exc_class,
1415
)
1516
from ..abc import Event, ObjectReceiveStream, ObjectSendStream
1617
from ..lowlevel import checkpoint
@@ -104,6 +105,11 @@ async def receive(self) -> T_co:
104105

105106
try:
106107
await receive_event.wait()
108+
except get_cancelled_exc_class():
109+
# Ignore the immediate cancellation if we already received an item, so
110+
# as not to lose it
111+
if not container:
112+
raise
107113
finally:
108114
self._state.waiting_receivers.pop(receive_event, None)
109115

@@ -230,6 +236,12 @@ async def send(self, item: T_contra) -> None:
230236
self._state.waiting_senders[send_event] = item
231237
try:
232238
await send_event.wait()
239+
except get_cancelled_exc_class():
240+
# Ignore the immediate cancellation if we already sent the item, so as
241+
# to not indicate failure despite success
242+
if send_event in self._state.waiting_senders:
243+
del self._state.waiting_senders[send_event]
244+
raise
233245
except BaseException:
234246
self._state.waiting_senders.pop(send_event, None)
235247
raise

0 commit comments

Comments
 (0)