From c3e1276229b9b29b0f830193707aba9b4e551acd Mon Sep 17 00:00:00 2001 From: "Jeong, YunWon" <69878+youknowone@users.noreply.github.com> Date: Tue, 13 Oct 2026 10:33:55 +0900 Subject: [PATCH] Release unused capacity after more short reads (#9089) Call shrink_to_fit on the result buffer in os.pread, os.getrandom, WindowsConsoleIO.read, _winapi.PeekNamedPipe, _winapi.ReadFile, _multiprocessing.recv and the openssl MemoryBIO.read. Assisted-by: Claude:claude-opus-5-5 Assisted-by: Grok:grok-4.7 --- crates/stdlib/src/multiprocessing.rs | 7 +++++-- crates/stdlib/src/openssl.rs | 1 + crates/vm/src/stdlib/_io.rs | 1 + crates/vm/src/stdlib/_winapi.rs | 6 ++++-- crates/vm/src/stdlib/posix.rs | 2 ++ 5 files changed, 13 insertions(+), 4 deletions(-) diff --git a/crates/stdlib/src/multiprocessing.rs b/crates/stdlib/src/multiprocessing.rs index 5c3356495..c992f90f7 100644 --- a/crates/stdlib/src/multiprocessing.rs +++ b/crates/stdlib/src/multiprocessing.rs @@ -408,8 +408,11 @@ mod _multiprocessing { #[pyfunction] fn recv(socket: usize, size: usize, vm: &VirtualMachine) -> PyResult> { - host_multiprocessing::recv_socket(socket as host_multiprocessing::RawSocket, size) - .map_err(|_| vm.new_last_os_error()) + let mut buf = + host_multiprocessing::recv_socket(socket as host_multiprocessing::RawSocket, size) + .map_err(|_| vm.new_last_os_error())?; + buf.shrink_to_fit(); + Ok(buf) } #[pyfunction] diff --git a/crates/stdlib/src/openssl.rs b/crates/stdlib/src/openssl.rs index 5470f7884..bba64f702 100644 --- a/crates/stdlib/src/openssl.rs +++ b/crates/stdlib/src/openssl.rs @@ -3706,6 +3706,7 @@ mod _ssl { } buf.truncate(nbytes as usize); + buf.shrink_to_fit(); Ok(buf) } } diff --git a/crates/vm/src/stdlib/_io.rs b/crates/vm/src/stdlib/_io.rs index 9bf3b3cfb..6c1fa064a 100644 --- a/crates/vm/src/stdlib/_io.rs +++ b/crates/vm/src/stdlib/_io.rs @@ -6949,6 +6949,7 @@ mod winconsoleio { } buf.truncate(read_len); + buf.shrink_to_fit(); Ok(vm.ctx.new_bytes(buf).into()) } diff --git a/crates/vm/src/stdlib/_winapi.rs b/crates/vm/src/stdlib/_winapi.rs index c47ea6823..6f495299a 100644 --- a/crates/vm/src/stdlib/_winapi.rs +++ b/crates/vm/src/stdlib/_winapi.rs @@ -768,7 +768,8 @@ mod _winapi { if size > 0 { let result = host_winapi::peek_named_pipe(handle.0, Some(size as u32)) .map_err(|e| e.to_pyexception(vm))?; - let buf = result.data.unwrap_or_default(); + let mut buf = result.data.unwrap_or_default(); + buf.shrink_to_fit(); let bytes: PyObjectRef = vm.ctx.new_bytes(buf).into(); Ok(vm .ctx @@ -886,9 +887,10 @@ mod _winapi { return Ok(result.into()); } - let result = vm + let mut result = vm .allow_threads(|| host_winapi::read_file(handle.0, size)) .map_err(|e| e.to_pyexception(vm))?; + result.data.shrink_to_fit(); Ok(vm .ctx .new_tuple(vec![ diff --git a/crates/vm/src/stdlib/posix.rs b/crates/vm/src/stdlib/posix.rs index 388771acb..26371c87e 100644 --- a/crates/vm/src/stdlib/posix.rs +++ b/crates/vm/src/stdlib/posix.rs @@ -1214,6 +1214,7 @@ pub mod module { match vm.allow_threads(|| rustpython_host_env::posix::pread(fd, &mut buffer, offset)) { Ok(n) => { buffer.truncate(n); + buffer.shrink_to_fit(); return Ok(vm.ctx.new_bytes(buffer)); } Err(err) if err.raw_os_error() == Some(libc::EINTR) => { @@ -2976,6 +2977,7 @@ pub mod module { .map_err(|_| vm.new_last_os_error())?; buf.set_len(len); } + buf.shrink_to_fit(); Ok(buf) }