Repository navigation
Conversation
…ites SocketStream.send_all() and POSIX FdStream.send_all() used the byte counts returned by send()/os.write() as memoryview element offsets. For a contiguous memoryview with itemsize > 1, a partial write could skip data and return successfully without sending the full buffer. Cast non-empty views to a one-dimensional byte view before slicing, so offsets and write return values are both in bytes. Empty views keep the previous early-return path because cast() rejects strided views, even empty ones. Fixes python-trio#3543
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3550 +/- ##
===============================================
Coverage 100.00000% 100.00000%
===============================================
Files 128 128
Lines 19474 19524 +50
Branches 1323 1328 +5
===============================================
+ Hits 19474 19524 +50
🚀 New features to boost your workflow:
|
|
A note on the 3 failing checks (Ubuntu/macOS pypy-3.11): all failures are |
Problem
SocketStream.send_all()and POSIXFdStream.send_all()used the byte counts returned bysend()/os.write()as memoryview element offsets. For a contiguous memoryview withitemsize > 1, a partial write could therefore skip data and return successfully without sending the full buffer — a silent truncation (reproduced: 1 MiB payload, only 512 KiB sent, no error).What changed
src/trio/_highlevel_socket.py(SocketStream.send_all) andsrc/trio/_unix_pipes.py(FdStream.send_all): after the existing empty-view early return, cast the view to a one-dimensional byte view (cast("B")) before entering the retry loop, so slice offsets and write return values are both in bytes. Empty views keep the old path becausecast()rejects strided views, even empty ones.newsfragments/3543.bugfix.rst.Verification
test_highlevel_socket.py(8 passed),test_unix_pipes.py(12 passed),test_highlevel_generic.py(2 passed);ruff checkandruff formatclean.Fixes #3543.
Note (out of scope):
_windows_pipes.py'ssend_allassertswritten == len(data), which compares bytes written against the element count — also wrong for typed views, but fail-loud rather than silent, and I can't verify a Windows change from here. Happy to follow up if wanted.