From bc8080a52f3343b092a5b9ff0c5b958073be8f65 Mon Sep 17 00:00:00 2001 From: Leesoo Ahn Date: Wed, 14 Oct 2026 20:40:37 +0900 Subject: [PATCH] Fix pwd.getpwuid raising OSError for unknown uids (#9106) When a uid does not exist, some NSS backends (systemd-userdb, sssd, LDAP) make getpwuid_r() return a non-zero errno such as ENOENT. POSIX expects success with a NULL result instead. That errno was surfacing as FileNotFoundError and broke test_pwd.test_errors. Match CPython's pwdmodule.c: raise MemoryError only for ENOMEM, and treat any other failure as "not found" (KeyError). Assisted-by: Antigravity:Claude Opus 5.5 --- crates/vm/src/stdlib/pwd.rs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/crates/vm/src/stdlib/pwd.rs b/crates/vm/src/stdlib/pwd.rs index 90a37d6d3..c2eb3391b 100644 --- a/crates/vm/src/stdlib/pwd.rs +++ b/crates/vm/src/stdlib/pwd.rs @@ -5,8 +5,8 @@ pub(crate) use pwd::module_def; #[pymodule] mod pwd { use crate::{ - PyResult, VirtualMachine, builtins::PyUtf8StrRef, convert::IntoPyException, exceptions, - function::ArgIndex, types::PyStructSequence, + PyResult, VirtualMachine, builtins::PyUtf8StrRef, exceptions, function::ArgIndex, + types::PyStructSequence, }; use core::hint::cold_path; use rustpython_host_env::pwd as host_pwd; @@ -67,12 +67,16 @@ mod pwd { #[pyfunction] fn getpwuid(uidobj: ArgIndex, vm: &VirtualMachine) -> PyResult { let uidobj = uidobj.into_int_ref(); - let uid_t = libc::uid_t::try_from(uidobj.as_bigint()).ok(); - let user = uid_t + let user = match libc::uid_t::try_from(uidobj.as_bigint()) + .ok() .map(host_pwd::getpwuid) - .transpose() - .map_err(|err| err.into_pyexception(vm))? - .flatten(); + { + Some(Ok(user)) => user, + Some(Err(err)) if err.raw_os_error() == Some(libc::ENOMEM) => { + return Err(vm.no_memory_error()); + } + _ => None, + }; let user = user.ok_or_else(|| { vm.new_key_error( vm.ctx