1 diff -up Python-3.3.0b1/Include/modsupport.h.uid-gid-overflows Python-3.3.0b1/Include/modsupport.h
2 --- Python-3.3.0b1/Include/modsupport.h.uid-gid-overflows 2012-06-26 16:19:40.000000000 -0400
3 +++ Python-3.3.0b1/Include/modsupport.h 2012-07-20 14:21:46.854688763 -0400
4 @@ -8,6 +8,7 @@ extern "C" {
5 /* Module support interface */
8 +#include <sys/types.h>
10 /* If PY_SSIZE_T_CLEAN is defined, each functions treats #-specifier
12 @@ -125,6 +126,17 @@ PyAPI_FUNC(PyObject *) PyModule_Create2(
13 PyAPI_DATA(char *) _Py_PackageContext;
17 + Non-standard extension: support for dealing with uid_t and gid_t without
21 +PyAPI_FUNC(PyObject *) _PyObject_FromUid(uid_t uid);
22 +PyAPI_FUNC(PyObject *) _PyObject_FromGid(gid_t gid);
24 +PyAPI_FUNC(int) _PyArg_ParseUid(PyObject *in_obj, uid_t *out_uid);
25 +PyAPI_FUNC(int) _PyArg_ParseGid(PyObject *in_obj, gid_t *out_gid);
30 diff -up Python-3.3.0b1/Lib/test/test_os.py.uid-gid-overflows Python-3.3.0b1/Lib/test/test_os.py
31 --- Python-3.3.0b1/Lib/test/test_os.py.uid-gid-overflows 2012-06-26 16:19:48.000000000 -0400
32 +++ Python-3.3.0b1/Lib/test/test_os.py 2012-07-20 14:21:46.856688739 -0400
33 @@ -1174,30 +1174,36 @@ if sys.platform != 'win32':
34 def test_setuid(self):
36 self.assertRaises(os.error, os.setuid, 0)
37 + self.assertRaises(TypeError, os.setuid, 'not an int')
38 self.assertRaises(OverflowError, os.setuid, 1<<32)
40 if hasattr(os, 'setgid'):
41 def test_setgid(self):
43 self.assertRaises(os.error, os.setgid, 0)
44 + self.assertRaises(TypeError, os.setgid, 'not an int')
45 self.assertRaises(OverflowError, os.setgid, 1<<32)
47 if hasattr(os, 'seteuid'):
48 def test_seteuid(self):
50 self.assertRaises(os.error, os.seteuid, 0)
51 + self.assertRaises(TypeError, os.seteuid, 'not an int')
52 self.assertRaises(OverflowError, os.seteuid, 1<<32)
54 if hasattr(os, 'setegid'):
55 def test_setegid(self):
57 self.assertRaises(os.error, os.setegid, 0)
58 + self.assertRaises(TypeError, os.setegid, 'not an int')
59 self.assertRaises(OverflowError, os.setegid, 1<<32)
61 if hasattr(os, 'setreuid'):
62 def test_setreuid(self):
64 self.assertRaises(os.error, os.setreuid, 0, 0)
65 + self.assertRaises(TypeError, os.setreuid, 'not an int', 0)
66 + self.assertRaises(TypeError, os.setreuid, 0, 'not an int')
67 self.assertRaises(OverflowError, os.setreuid, 1<<32, 0)
68 self.assertRaises(OverflowError, os.setreuid, 0, 1<<32)
70 @@ -1212,6 +1218,8 @@ if sys.platform != 'win32':
71 def test_setregid(self):
73 self.assertRaises(os.error, os.setregid, 0, 0)
74 + self.assertRaises(TypeError, os.setregid, 'not an int', 0)
75 + self.assertRaises(TypeError, os.setregid, 0, 'not an int')
76 self.assertRaises(OverflowError, os.setregid, 1<<32, 0)
77 self.assertRaises(OverflowError, os.setregid, 0, 1<<32)
79 diff -up Python-3.3.0b1/Lib/test/test_posix.py.uid-gid-overflows Python-3.3.0b1/Lib/test/test_posix.py
80 --- Python-3.3.0b1/Lib/test/test_posix.py.uid-gid-overflows 2012-06-26 16:19:48.000000000 -0400
81 +++ Python-3.3.0b1/Lib/test/test_posix.py 2012-07-20 14:21:46.857688726 -0400
82 @@ -387,10 +387,17 @@ class PosixTester(unittest.TestCase):
84 self.assertTrue(stat.S_ISFIFO(posix.stat(support.TESTFN).st_mode))
86 - def _test_all_chown_common(self, chown_func, first_param):
87 + def _test_all_chown_common(self, chown_func, stat_func, first_param):
88 """Common code for chown, fchown and lchown tests."""
89 # test a successful chown call
90 chown_func(first_param, os.getuid(), os.getgid())
91 + self.assertEqual(stat_func(first_param).st_uid, os.getuid())
92 + self.assertEqual(stat_func(first_param).st_gid, os.getgid())
94 + # verify that -1 works as a "do-nothing" option:
95 + chown_func(first_param, -1, -1)
96 + self.assertEqual(stat_func(first_param).st_uid, os.getuid())
97 + self.assertEqual(stat_func(first_param).st_gid, os.getgid())
101 @@ -421,7 +428,7 @@ class PosixTester(unittest.TestCase):
104 support.create_empty_file(support.TESTFN)
105 - self._test_all_chown_common(posix.chown, support.TESTFN)
106 + self._test_all_chown_common(posix.chown, posix.stat, support.TESTFN)
108 @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()")
109 def test_fchown(self):
110 @@ -431,7 +438,7 @@ class PosixTester(unittest.TestCase):
111 test_file = open(support.TESTFN, 'w')
113 fd = test_file.fileno()
114 - self._test_all_chown_common(posix.fchown, fd)
115 + self._test_all_chown_common(posix.fchown, posix.fstat, fd)
119 @@ -440,7 +447,7 @@ class PosixTester(unittest.TestCase):
120 os.unlink(support.TESTFN)
122 os.symlink(_DUMMY_SYMLINK, support.TESTFN)
123 - self._test_all_chown_common(posix.lchown, support.TESTFN)
124 + self._test_all_chown_common(posix.lchown, posix.lstat, support.TESTFN)
126 def test_chdir(self):
127 if hasattr(posix, 'chdir'):
128 diff -up Python-3.3.0b1/Lib/test/test_pwd.py.uid-gid-overflows Python-3.3.0b1/Lib/test/test_pwd.py
129 --- Python-3.3.0b1/Lib/test/test_pwd.py.uid-gid-overflows 2012-06-26 16:19:48.000000000 -0400
130 +++ Python-3.3.0b1/Lib/test/test_pwd.py 2012-07-20 14:21:46.857688726 -0400
131 @@ -87,9 +87,9 @@ class PwdTest(unittest.TestCase):
132 # In some cases, byuids isn't a complete list of all users in the
133 # system, so if we try to pick a value not in byuids (via a perturbing
134 # loop, say), pwd.getpwuid() might still be able to find data for that
135 - # uid. Using sys.maxint may provoke the same problems, but hopefully
136 + # uid. Using 2**32 - 2 may provoke the same problems, but hopefully
137 # it will be a more repeatable failure.
138 - fakeuid = sys.maxsize
139 + fakeuid = 2**32 - 2
140 self.assertNotIn(fakeuid, byuids)
141 self.assertRaises(KeyError, pwd.getpwuid, fakeuid)
143 diff -up Python-3.3.0b1/Modules/grpmodule.c.uid-gid-overflows Python-3.3.0b1/Modules/grpmodule.c
144 --- Python-3.3.0b1/Modules/grpmodule.c.uid-gid-overflows 2012-06-26 16:19:54.000000000 -0400
145 +++ Python-3.3.0b1/Modules/grpmodule.c 2012-07-20 14:21:46.858688713 -0400
146 @@ -69,7 +69,7 @@ mkgrent(struct group *p)
150 - SET(setIndex++, PyLong_FromLong((long) p->gr_gid));
151 + SET(setIndex++, _PyObject_FromGid(p->gr_gid));
155 @@ -84,18 +84,16 @@ mkgrent(struct group *p)
157 grp_getgrgid(PyObject *self, PyObject *pyo_id)
159 - PyObject *py_int_id;
164 - py_int_id = PyNumber_Long(pyo_id);
167 - gid = PyLong_AS_LONG(py_int_id);
168 - Py_DECREF(py_int_id);
169 + if (!_PyArg_ParseGid(pyo_id, &gid)) {
173 if ((p = getgrgid(gid)) == NULL) {
174 - PyErr_Format(PyExc_KeyError, "getgrgid(): gid not found: %d", gid);
175 + PyErr_Format(PyExc_KeyError,
176 + "getgrgid(): gid not found: %lu", (unsigned long)gid);
180 diff -up Python-3.3.0b1/Modules/posixmodule.c.uid-gid-overflows Python-3.3.0b1/Modules/posixmodule.c
181 --- Python-3.3.0b1/Modules/posixmodule.c.uid-gid-overflows 2012-07-20 14:21:46.788689588 -0400
182 +++ Python-3.3.0b1/Modules/posixmodule.c 2012-07-20 14:24:19.626778849 -0400
183 @@ -2151,8 +2151,8 @@ _pystat_fromstructstat(STRUCT_STAT *st)
184 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
186 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
187 - PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
188 - PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
189 + PyStructSequence_SET_ITEM(v, 4, _PyObject_FromUid(st->st_uid));
190 + PyStructSequence_SET_ITEM(v, 5, _PyObject_FromGid(st->st_gid));
191 #ifdef HAVE_LARGEFILE_SUPPORT
192 PyStructSequence_SET_ITEM(v, 6,
193 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
194 @@ -2957,7 +2957,6 @@ static PyObject *
195 posix_chown(PyObject *self, PyObject *args, PyObject *kwargs)
201 int dir_fd = DEFAULT_DIR_FD;
202 @@ -2971,9 +2970,10 @@ posix_chown(PyObject *self, PyObject *ar
206 - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&ll|$O&p:chown", keywords,
207 + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&O&|$O&p:chown", keywords,
208 path_converter, &path,
210 + _PyArg_ParseUid, &uid,
211 + _PyArg_ParseGid, &gid,
213 dir_fd_converter, &dir_fd,
215 @@ -3004,8 +3004,6 @@ posix_chown(PyObject *self, PyObject *ar
218 Py_BEGIN_ALLOW_THREADS
219 - uid = (uid_t)uid_l;
220 - gid = (uid_t)gid_l;
223 result = fchown(path.fd, uid, gid);
224 @@ -3049,12 +3047,15 @@ static PyObject *
225 posix_fchown(PyObject *self, PyObject *args)
232 - if (!PyArg_ParseTuple(args, "ill:fchown", &fd, &uid, &gid))
233 + if (!PyArg_ParseTuple(args, "iO&O&:chown", &fd,
234 + _PyArg_ParseUid, &uid,
235 + _PyArg_ParseGid, &gid))
237 Py_BEGIN_ALLOW_THREADS
238 - res = fchown(fd, (uid_t) uid, (gid_t) gid);
239 + res = fchown(fd, uid, gid);
242 return posix_error();
243 @@ -3074,15 +3075,17 @@ posix_lchown(PyObject *self, PyObject *a
251 - if (!PyArg_ParseTuple(args, "O&ll:lchown",
252 + if (!PyArg_ParseTuple(args, "O&O&O&:lchown",
253 PyUnicode_FSConverter, &opath,
255 + _PyArg_ParseUid, &uid,
256 + _PyArg_ParseGid, &gid))
258 path = PyBytes_AsString(opath);
259 Py_BEGIN_ALLOW_THREADS
260 - res = lchown(path, (uid_t) uid, (gid_t) gid);
261 + res = lchown(path, uid, gid);
264 return posix_error_with_allocated_filename(opath);
265 @@ -6184,7 +6187,7 @@ Return the current process's effective g
267 posix_getegid(PyObject *self, PyObject *noargs)
269 - return PyLong_FromLong((long)getegid());
270 + return _PyObject_FromGid(getegid());
274 @@ -6197,7 +6200,7 @@ Return the current process's effective u
276 posix_geteuid(PyObject *self, PyObject *noargs)
278 - return PyLong_FromLong((long)geteuid());
279 + return _PyObject_FromUid(geteuid());
283 @@ -6210,7 +6213,7 @@ Return the current process's group id.")
285 posix_getgid(PyObject *self, PyObject *noargs)
287 - return PyLong_FromLong((long)getgid());
288 + return _PyObject_FromGid(getgid());
292 @@ -6349,7 +6352,7 @@ posix_getgroups(PyObject *self, PyObject
293 if (result != NULL) {
295 for (i = 0; i < n; ++i) {
296 - PyObject *o = PyLong_FromLong((long)alt_grouplist[i]);
297 + PyObject *o = _PyObject_FromGid(alt_grouplist[i]);
301 @@ -6380,14 +6383,15 @@ posix_initgroups(PyObject *self, PyObjec
308 - if (!PyArg_ParseTuple(args, "O&l:initgroups",
309 - PyUnicode_FSConverter, &oname, &gid))
310 + if (!PyArg_ParseTuple(args, "O&O&:initgroups",
311 + PyUnicode_FSConverter, &oname,
312 + _PyArg_ParseGid, &gid))
314 username = PyBytes_AS_STRING(oname);
316 - res = initgroups(username, (gid_t) gid);
317 + res = initgroups(username, gid);
320 return PyErr_SetFromErrno(PyExc_OSError);
321 @@ -6562,7 +6566,7 @@ Return the current process's user id.");
323 posix_getuid(PyObject *self, PyObject *noargs)
325 - return PyLong_FromLong((long)getuid());
326 + return _PyObject_FromUid(getuid());
330 @@ -6702,15 +6706,9 @@ Set the current process's user id.");
332 posix_setuid(PyObject *self, PyObject *args)
336 - if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
339 - if (uid != uid_arg) {
340 - PyErr_SetString(PyExc_OverflowError, "user id too big");
341 + if (!PyArg_ParseTuple(args, "O&:setuid", _PyArg_ParseUid, &uid))
345 return posix_error();
347 @@ -6727,15 +6725,9 @@ Set the current process's effective user
349 posix_seteuid (PyObject *self, PyObject *args)
353 - if (!PyArg_ParseTuple(args, "l", &euid_arg))
354 + if (!PyArg_ParseTuple(args, "O&:seteuid", _PyArg_ParseUid, &euid))
357 - if (euid != euid_arg) {
358 - PyErr_SetString(PyExc_OverflowError, "user id too big");
361 if (seteuid(euid) < 0) {
362 return posix_error();
364 @@ -6753,15 +6745,9 @@ Set the current process's effective grou
366 posix_setegid (PyObject *self, PyObject *args)
370 - if (!PyArg_ParseTuple(args, "l", &egid_arg))
373 - if (egid != egid_arg) {
374 - PyErr_SetString(PyExc_OverflowError, "group id too big");
375 + if (!PyArg_ParseTuple(args, "O&:setegid", _PyArg_ParseGid, &egid))
378 if (setegid(egid) < 0) {
379 return posix_error();
381 @@ -6779,23 +6765,11 @@ Set the current process's real and effec
383 posix_setreuid (PyObject *self, PyObject *args)
385 - long ruid_arg, euid_arg;
387 - if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
389 - if (ruid_arg == -1)
390 - ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
392 - ruid = ruid_arg; /* otherwise, assign from our long */
393 - if (euid_arg == -1)
397 - if ((euid_arg != -1 && euid != euid_arg) ||
398 - (ruid_arg != -1 && ruid != ruid_arg)) {
399 - PyErr_SetString(PyExc_OverflowError, "user id too big");
400 + if (!PyArg_ParseTuple(args, "O&O&",
401 + _PyArg_ParseUid, &ruid,
402 + _PyArg_ParseUid, &euid))
405 if (setreuid(ruid, euid) < 0) {
406 return posix_error();
408 @@ -6813,23 +6787,11 @@ Set the current process's real and effec
410 posix_setregid (PyObject *self, PyObject *args)
412 - long rgid_arg, egid_arg;
414 - if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
416 - if (rgid_arg == -1)
417 - rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
419 - rgid = rgid_arg; /* otherwise, assign from our long */
420 - if (egid_arg == -1)
424 - if ((egid_arg != -1 && egid != egid_arg) ||
425 - (rgid_arg != -1 && rgid != rgid_arg)) {
426 - PyErr_SetString(PyExc_OverflowError, "group id too big");
427 + if (!PyArg_ParseTuple(args, "O&O&",
428 + _PyArg_ParseGid, &rgid,
429 + _PyArg_ParseGid, &egid))
432 if (setregid(rgid, egid) < 0) {
433 return posix_error();
435 @@ -6847,15 +6809,9 @@ Set the current process's group id.");
437 posix_setgid(PyObject *self, PyObject *args)
441 - if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
442 + if (!PyArg_ParseTuple(args, "O&:setgid", _PyArg_ParseGid, &gid))
445 - if (gid != gid_arg) {
446 - PyErr_SetString(PyExc_OverflowError, "group id too big");
450 return posix_error();
452 @@ -6888,27 +6844,9 @@ posix_setgroups(PyObject *self, PyObject
453 elem = PySequence_GetItem(groups, i);
456 - if (!PyLong_Check(elem)) {
457 - PyErr_SetString(PyExc_TypeError,
458 - "groups must be integers");
459 + if (!_PyArg_ParseGid(elem, &grouplist[i])) {
463 - unsigned long x = PyLong_AsUnsignedLong(elem);
464 - if (PyErr_Occurred()) {
465 - PyErr_SetString(PyExc_TypeError,
466 - "group id too big");
471 - /* read back the value to see if it fitted in gid_t */
472 - if (grouplist[i] != x) {
473 - PyErr_SetString(PyExc_TypeError,
474 - "group id too big");
481 @@ -10388,9 +10326,11 @@ Set the current process's real, effectiv
483 posix_setresuid (PyObject *self, PyObject *args)
485 - /* We assume uid_t is no larger than a long. */
486 - long ruid, euid, suid;
487 - if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
488 + uid_t ruid, euid, suid;
489 + if (!PyArg_ParseTuple(args, "O&O&O&",
490 + _PyArg_ParseUid, &ruid,
491 + _PyArg_ParseUid, &euid,
492 + _PyArg_ParseUid, &suid))
494 if (setresuid(ruid, euid, suid) < 0)
495 return posix_error();
496 @@ -10406,9 +10346,11 @@ Set the current process's real, effectiv
498 posix_setresgid (PyObject *self, PyObject *args)
500 - /* We assume uid_t is no larger than a long. */
501 - long rgid, egid, sgid;
502 - if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
503 + gid_t rgid, egid, sgid;
504 + if (!PyArg_ParseTuple(args, "O&O&O&",
505 + _PyArg_ParseGid, &rgid,
506 + _PyArg_ParseGid, &egid,
507 + _PyArg_ParseGid, &sgid))
509 if (setresgid(rgid, egid, sgid) < 0)
510 return posix_error();
511 @@ -10425,14 +10367,13 @@ static PyObject*
512 posix_getresuid (PyObject *self, PyObject *noargs)
514 uid_t ruid, euid, suid;
515 - long l_ruid, l_euid, l_suid;
516 + PyObject *obj_ruid, *obj_euid, *obj_suid;
517 if (getresuid(&ruid, &euid, &suid) < 0)
518 return posix_error();
519 - /* Force the values into long's as we don't know the size of uid_t. */
523 - return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
524 + obj_ruid = _PyObject_FromUid(ruid);
525 + obj_euid = _PyObject_FromUid(euid);
526 + obj_suid = _PyObject_FromUid(suid);
527 + return Py_BuildValue("(NNN)", obj_ruid, obj_euid, obj_suid);
531 @@ -10445,14 +10386,13 @@ static PyObject*
532 posix_getresgid (PyObject *self, PyObject *noargs)
534 uid_t rgid, egid, sgid;
535 - long l_rgid, l_egid, l_sgid;
536 + PyObject *obj_rgid, *obj_egid, *obj_sgid;
537 if (getresgid(&rgid, &egid, &sgid) < 0)
538 return posix_error();
539 - /* Force the values into long's as we don't know the size of uid_t. */
543 - return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
544 + obj_rgid = _PyObject_FromGid(rgid);
545 + obj_egid = _PyObject_FromGid(egid);
546 + obj_sgid = _PyObject_FromGid(sgid);
547 + return Py_BuildValue("(NNN)", obj_rgid, obj_egid, obj_sgid);
551 diff -up Python-3.3.0b1/Modules/pwdmodule.c.uid-gid-overflows Python-3.3.0b1/Modules/pwdmodule.c
552 --- Python-3.3.0b1/Modules/pwdmodule.c.uid-gid-overflows 2012-06-26 16:19:54.000000000 -0400
553 +++ Python-3.3.0b1/Modules/pwdmodule.c 2012-07-20 14:21:46.861688675 -0400
554 @@ -74,8 +74,8 @@ mkpwent(struct passwd *p)
556 SETS(setIndex++, p->pw_passwd);
558 - SETI(setIndex++, p->pw_uid);
559 - SETI(setIndex++, p->pw_gid);
560 + PyStructSequence_SET_ITEM(v, setIndex++, _PyObject_FromUid(p->pw_uid));
561 + PyStructSequence_SET_ITEM(v, setIndex++, _PyObject_FromGid(p->pw_gid));
563 SETS(setIndex++, "");
565 @@ -104,13 +104,14 @@ See help(pwd) for more on password datab
567 pwd_getpwuid(PyObject *self, PyObject *args)
572 - if (!PyArg_ParseTuple(args, "I:getpwuid", &uid))
573 + if (!PyArg_ParseTuple(args, "O&:getpwuid",
574 + _PyArg_ParseUid, &uid))
576 if ((p = getpwuid(uid)) == NULL) {
577 PyErr_Format(PyExc_KeyError,
578 - "getpwuid(): uid not found: %d", uid);
579 + "getpwuid(): uid not found: %lu", (unsigned long)uid);
583 diff -up Python-3.3.0b1/Python/getargs.c.uid-gid-overflows Python-3.3.0b1/Python/getargs.c
584 --- Python-3.3.0b1/Python/getargs.c.uid-gid-overflows 2012-06-26 16:19:57.000000000 -0400
585 +++ Python-3.3.0b1/Python/getargs.c 2012-07-20 14:21:46.861688675 -0400
594 @@ -1807,6 +1808,102 @@ _PyArg_NoKeywords(const char *funcname,
600 +_PyObject_FromUid(uid_t uid)
602 + return PyLong_FromUnsignedLong((uid_t)uid);
606 +_PyObject_FromGid(gid_t gid)
608 + return PyLong_FromUnsignedLong((gid_t)gid);
612 +_PyArg_ParseUid(PyObject *in_obj, uid_t *out_uid)
614 + PyObject *index, *number = NULL;
620 + index = PyNumber_Index(in_obj);
621 + if (index != NULL) {
622 + number = PyNumber_Long(index);
625 + if (number == NULL) {
626 + PyErr_SetString(PyExc_TypeError, "user id must be integer");
630 + /* Special case: support -1 (e.g. for use by chown) */
631 + sl = PyLong_AsLong(number);
632 + if (PyErr_Occurred()) {
634 + } else if (sl == -1) {
636 + *out_uid = (uid_t)-1;
640 + /* Otherwise, it must be >= 0 */
641 + ul = PyLong_AsUnsignedLong(number);
644 + /* read back the value to see if it fitted in uid_t */
645 + if (PyErr_Occurred() || *out_uid != ul) {
646 + PyErr_SetString(PyExc_OverflowError,
647 + "user id is not in range(-1, 2^32-1)");
654 +_PyArg_ParseGid(PyObject *in_obj, gid_t *out_gid)
656 + PyObject *index, *number = NULL;
662 + index = PyNumber_Index(in_obj);
663 + if (index != NULL) {
664 + number = PyNumber_Long(index);
667 + if (number == NULL) {
668 + PyErr_SetString(PyExc_TypeError, "group id must be integer");
672 + /* Special case: support -1 (e.g. for use by chown) */
673 + sl = PyLong_AsLong(number);
674 + if (PyErr_Occurred()) {
676 + } else if (sl == -1) {
678 + *out_gid = (gid_t)-1;
682 + ul = PyLong_AsUnsignedLong(number);
685 + /* read back the value to see if it fitted in gid_t */
686 + if (PyErr_Occurred() || *out_gid != ul) {
687 + PyErr_SetString(PyExc_OverflowError,
688 + "group id is not in range(-1, 2^32-1)");