Skip to content

Commit a27c3ae

Browse files
gh-48511: Make pwd and grp expose inner errors
Distinguish between the case when the user/group does not exist and error conditions. If the user does not exit, raise KeyError as now, for errors raise OSError.
1 parent 81bf10e commit a27c3ae

File tree

3 files changed

+54
-32
lines changed

3 files changed

+54
-32
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
The Unix user (:func:`pwd.getpwuid`, :func:`pwd.getpwnam`) and group (
2+
:func:`grp.getgrgid`, :func:`grp.getgrnam`) database functions now
3+
differentiate between a lack of record (:exc:`KeyError` is risen, the current behaviour)
4+
and a database access error (:exc:`OSError` is risen).
5+
6+
Based on a patch by Oleg Iarygin.

Modules/grpmodule.c

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -158,21 +158,25 @@ grp_getgrgid_impl(PyObject *module, PyObject *id)
158158
p = getgrgid(gid);
159159
#endif
160160
if (p == NULL) {
161-
PyMem_RawFree(buf);
162161
if (nomem == 1) {
163-
return PyErr_NoMemory();
162+
retval = PyErr_NoMemory();
163+
}
164+
else if (errno == 0) {
165+
PyObject *gid_obj = _PyLong_FromGid(gid);
166+
if (gid_obj == NULL)
167+
return NULL;
168+
retval = PyErr_Format(PyExc_KeyError,
169+
"getgrgid(): gid not found: %S", gid_obj);
170+
Py_DECREF(gid_obj);
171+
}
172+
else {
173+
retval = PyErr_SetFromErrno(PyExc_OSError);
164174
}
165-
PyObject *gid_obj = _PyLong_FromGid(gid);
166-
if (gid_obj == NULL)
167-
return NULL;
168-
PyErr_Format(PyExc_KeyError, "getgrgid(): gid not found: %S", gid_obj);
169-
Py_DECREF(gid_obj);
170-
return NULL;
171175
}
172-
retval = mkgrent(module, p);
173-
#ifdef HAVE_GETGRGID_R
176+
else {
177+
retval = mkgrent(module, p);
178+
}
174179
PyMem_RawFree(buf);
175-
#endif
176180
return retval;
177181
}
178182

@@ -240,14 +244,19 @@ grp_getgrnam_impl(PyObject *module, PyObject *name)
240244
#endif
241245
if (p == NULL) {
242246
if (nomem == 1) {
243-
PyErr_NoMemory();
247+
retval = PyErr_NoMemory();
248+
}
249+
else if (errno == 0) {
250+
retval = PyErr_Format(PyExc_KeyError,
251+
"getgrnam(): name not found: %R", name);
244252
}
245253
else {
246-
PyErr_Format(PyExc_KeyError, "getgrnam(): name not found: %R", name);
254+
retval = PyErr_SetFromErrno(PyExc_OSError);
247255
}
248-
goto out;
249256
}
250-
retval = mkgrent(module, p);
257+
else {
258+
retval = mkgrent(module, p);
259+
}
251260
out:
252261
PyMem_RawFree(buf);
253262
Py_DECREF(bytes);

Modules/pwdmodule.c

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -178,22 +178,25 @@ pwd_getpwuid(PyObject *module, PyObject *uidobj)
178178
p = getpwuid(uid);
179179
#endif
180180
if (p == NULL) {
181-
PyMem_RawFree(buf);
182181
if (nomem == 1) {
183-
return PyErr_NoMemory();
182+
retval = PyErr_NoMemory();
183+
}
184+
else if (errno == 0) {
185+
PyObject *uid_obj = _PyLong_FromUid(uid);
186+
if (uid_obj == NULL)
187+
return NULL;
188+
retval = PyErr_Format(PyExc_KeyError,
189+
"getpwuid(): uid not found: %S", uid_obj);
190+
Py_DECREF(uid_obj);
191+
}
192+
else {
193+
retval = PyErr_SetFromErrno(PyExc_OSError);
184194
}
185-
PyObject *uid_obj = _PyLong_FromUid(uid);
186-
if (uid_obj == NULL)
187-
return NULL;
188-
PyErr_Format(PyExc_KeyError,
189-
"getpwuid(): uid not found: %S", uid_obj);
190-
Py_DECREF(uid_obj);
191-
return NULL;
192195
}
193-
retval = mkpwent(module, p);
194-
#ifdef HAVE_GETPWUID_R
196+
else {
197+
retval = mkpwent(module, p);
198+
}
195199
PyMem_RawFree(buf);
196-
#endif
197200
return retval;
198201
}
199202

@@ -262,15 +265,19 @@ pwd_getpwnam_impl(PyObject *module, PyObject *name)
262265
#endif
263266
if (p == NULL) {
264267
if (nomem == 1) {
265-
PyErr_NoMemory();
268+
retval = PyErr_NoMemory();
269+
}
270+
else if (errno == 0) {
271+
retval = PyErr_Format(PyExc_KeyError,
272+
"getpwnam(): name not found: %R", name);
266273
}
267274
else {
268-
PyErr_Format(PyExc_KeyError,
269-
"getpwnam(): name not found: %R", name);
275+
retval = PyErr_SetFromErrno(PyExc_OSError);
270276
}
271-
goto out;
272277
}
273-
retval = mkpwent(module, p);
278+
else {
279+
retval = mkpwent(module, p);
280+
}
274281
out:
275282
PyMem_RawFree(buf);
276283
Py_DECREF(bytes);

0 commit comments

Comments
 (0)