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
This commit is contained in:
Leesoo Ahn authored and GitHub committed 2026-10-14 20:40:37 +09:00
1 parent 28393e932d
commit bc8080a52f
1 file changed
+11 -7
+11 -7
View File
@@ -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<PasswdData> {
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