| :cmacro:`PyBUF_FULL` | This is equivalent to ``(PyBUF_INDIRECT | |
| | PyBUF_FORMAT | PyBUF_WRITABLE)``. |
+------------------------------+---------------------------------------------------+
- | :cmacro:`PyBUF_FULL_RO`` | This is equivalent to ``(PyBUF_INDIRECT | |
+ | :cmacro:`PyBUF_FULL_RO` | This is equivalent to ``(PyBUF_INDIRECT | |
| | PyBUF_FORMAT)``. |
+------------------------------+---------------------------------------------------+
| :cmacro:`PyBUF_CONTIG` | This is equivalent to ``(PyBUF_ND | |
single: lock, interpreter
The Python interpreter is not fully thread safe. In order to support
-multi-threaded Python programs, there's a global lock that must be held by the
-current thread before it can safely access Python objects. Without the lock,
-even the simplest operations could cause problems in a multi-threaded program:
-for example, when two threads simultaneously increment the reference count of
-the same object, the reference count could end up being incremented only once
-instead of twice.
+multi-threaded Python programs, there's a global lock, called the :dfn:`global
+interpreter lock` or :dfn:`GIL`, that must be held by the current thread before
+it can safely access Python objects. Without the lock, even the simplest
+operations could cause problems in a multi-threaded program: for example, when
+two threads simultaneously increment the reference count of the same object, the
+reference count could end up being incremented only once instead of twice.
.. index:: single: setcheckinterval() (in module sys)
interpreter lock has the following simple structure::
Save the thread state in a local variable.
- Release the interpreter lock.
+ Release the global interpreter lock.
...Do some blocking I/O operation...
- Reacquire the interpreter lock.
+ Reacquire the global interpreter lock.
Restore the thread state from the local variable.
This is so common that a pair of macros exists to simplify it::
hidden local variable; the :cmacro:`Py_END_ALLOW_THREADS` macro closes the
block. Another advantage of using these two macros is that when Python is
compiled without thread support, they are defined empty, thus saving the thread
-state and lock manipulations.
+state and GIL manipulations.
When thread support is enabled, the block above expands to the following code::
saves and restores the value of the global variable :cdata:`errno`, since the
lock manipulation does not guarantee that :cdata:`errno` is left alone. Also,
when thread support is disabled, :cfunc:`PyEval_SaveThread` and
-:cfunc:`PyEval_RestoreThread` don't manipulate the lock; in this case,
+:cfunc:`PyEval_RestoreThread` don't manipulate the GIL; in this case,
:cfunc:`PyEval_ReleaseLock` and :cfunc:`PyEval_AcquireLock` are not available.
This is done so that dynamically loaded extensions compiled with thread support
enabled can be loaded by an interpreter that was compiled with disabled thread
.. index:: module: _thread
- When only the main thread exists, no lock operations are needed. This is a
+ When only the main thread exists, no GIL operations are needed. This is a
common situation (most Python programs do not use threads), and the lock
- operations slow the interpreter down a bit. Therefore, the lock is not created
- initially. This situation is equivalent to having acquired the lock: when
- there is only a single thread, all object accesses are safe. Therefore, when
- this function initializes the lock, it also acquires it. Before the Python
- :mod:`_thread` module creates a new thread, knowing that either it has the lock
- or the lock hasn't been created yet, it calls :cfunc:`PyEval_InitThreads`. When
- this call returns, it is guaranteed that the lock has been created and that the
- calling thread has acquired it.
+ operations slow the interpreter down a bit. Therefore, the lock is not
+ created initially. This situation is equivalent to having acquired the lock:
+ when there is only a single thread, all object accesses are safe. Therefore,
+ when this function initializes the global interpreter lock, it also acquires
+ it. Before the Python :mod:`_thread` module creates a new thread, knowing
+ that either it has the lock or the lock hasn't been created yet, it calls
+ :cfunc:`PyEval_InitThreads`. When this call returns, it is guaranteed that
+ the lock has been created and that the calling thread has acquired it.
It is **not** safe to call this function when it is unknown which thread (if
any) currently has the global interpreter lock.
.. cfunction:: int PyEval_ThreadsInitialized()
Returns a non-zero value if :cfunc:`PyEval_InitThreads` has been called. This
- function can be called without holding the lock, and therefore can be used to
+ function can be called without holding the GIL, and therefore can be used to
avoid calls to the locking API when running single-threaded. This function is
not available when thread support is disabled at compile time.
.. cfunction:: PyThreadState* PyEval_SaveThread()
- Release the interpreter lock (if it has been created and thread support is
- enabled) and reset the thread state to *NULL*, returning the previous thread
- state (which is not *NULL*). If the lock has been created, the current thread
- must have acquired it. (This function is available even when thread support is
- disabled at compile time.)
+ Release the global interpreter lock (if it has been created and thread
+ support is enabled) and reset the thread state to *NULL*, returning the
+ previous thread state (which is not *NULL*). If the lock has been created,
+ the current thread must have acquired it. (This function is available even
+ when thread support is disabled at compile time.)
.. cfunction:: void PyEval_RestoreThread(PyThreadState *tstate)
- Acquire the interpreter lock (if it has been created and thread support is
- enabled) and set the thread state to *tstate*, which must not be *NULL*. If the
- lock has been created, the current thread must not have acquired it, otherwise
- deadlock ensues. (This function is available even when thread support is
- disabled at compile time.)
+ Acquire the global interpreter lock (if it has been created and thread
+ support is enabled) and set the thread state to *tstate*, which must not be
+ *NULL*. If the lock has been created, the current thread must not have
+ acquired it, otherwise deadlock ensues. (This function is available even
+ when thread support is disabled at compile time.)
.. cfunction:: void PyEval_ReInitThreads()
declaration. It is a no-op when thread support is disabled at compile time.
All of the following functions are only available when thread support is enabled
-at compile time, and must be called only when the interpreter lock has been
-created.
+at compile time, and must be called only when the global interpreter lock has
+been created.
.. cfunction:: PyInterpreterState* PyInterpreterState_New()
- Create a new interpreter state object. The interpreter lock need not be held,
- but may be held if it is necessary to serialize calls to this function.
+ Create a new interpreter state object. The global interpreter lock need not
+ be held, but may be held if it is necessary to serialize calls to this
+ function.
.. cfunction:: void PyInterpreterState_Clear(PyInterpreterState *interp)
- Reset all information in an interpreter state object. The interpreter lock must
- be held.
+ Reset all information in an interpreter state object. The global interpreter
+ lock must be held.
.. cfunction:: void PyInterpreterState_Delete(PyInterpreterState *interp)
- Destroy an interpreter state object. The interpreter lock need not be held.
- The interpreter state must have been reset with a previous call to
+ Destroy an interpreter state object. The global interpreter lock need not be
+ held. The interpreter state must have been reset with a previous call to
:cfunc:`PyInterpreterState_Clear`.
.. cfunction:: PyThreadState* PyThreadState_New(PyInterpreterState *interp)
- Create a new thread state object belonging to the given interpreter object. The
- interpreter lock need not be held, but may be held if it is necessary to
- serialize calls to this function.
+ Create a new thread state object belonging to the given interpreter object.
+ The global interpreter lock need not be held, but may be held if it is
+ necessary to serialize calls to this function.
.. cfunction:: void PyThreadState_Clear(PyThreadState *tstate)
- Reset all information in a thread state object. The interpreter lock must be
- held.
+ Reset all information in a thread state object. The global interpreter lock
+ must be held.
.. cfunction:: void PyThreadState_Delete(PyThreadState *tstate)
- Destroy a thread state object. The interpreter lock need not be held. The
- thread state must have been reset with a previous call to
+ Destroy a thread state object. The global interpreter lock need not be held.
+ The thread state must have been reset with a previous call to
:cfunc:`PyThreadState_Clear`.
.. cfunction:: PyThreadState* PyThreadState_Get()
- Return the current thread state. The interpreter lock must be held. When the
- current thread state is *NULL*, this issues a fatal error (so that the caller
- needn't check for *NULL*).
+ Return the current thread state. The global interpreter lock must be held.
+ When the current thread state is *NULL*, this issues a fatal error (so that
+ the caller needn't check for *NULL*).
.. cfunction:: PyThreadState* PyThreadState_Swap(PyThreadState *tstate)
Swap the current thread state with the thread state given by the argument
- *tstate*, which may be *NULL*. The interpreter lock must be held.
+ *tstate*, which may be *NULL*. The global interpreter lock must be held.
.. cfunction:: PyObject* PyThreadState_GetDict()
.. cfunction:: PyGILState_STATE PyGILState_Ensure()
- Ensure that the current thread is ready to call the Python C API regardless of
- the current state of Python, or of its thread lock. This may be called as many
- times as desired by a thread as long as each call is matched with a call to
- :cfunc:`PyGILState_Release`. In general, other thread-related APIs may be used
- between :cfunc:`PyGILState_Ensure` and :cfunc:`PyGILState_Release` calls as long
- as the thread state is restored to its previous state before the Release(). For
- example, normal usage of the :cmacro:`Py_BEGIN_ALLOW_THREADS` and
- :cmacro:`Py_END_ALLOW_THREADS` macros is acceptable.
+ Ensure that the current thread is ready to call the Python C API regardless
+ of the current state of Python, or of the global interpreter lock. This may
+ be called as many times as desired by a thread as long as each call is
+ matched with a call to :cfunc:`PyGILState_Release`. In general, other
+ thread-related APIs may be used between :cfunc:`PyGILState_Ensure` and
+ :cfunc:`PyGILState_Release` calls as long as the thread state is restored to
+ its previous state before the Release(). For example, normal usage of the
+ :cmacro:`Py_BEGIN_ALLOW_THREADS` and :cmacro:`Py_END_ALLOW_THREADS` macros is
+ acceptable.
The return value is an opaque "handle" to the thread state when
:cfunc:`PyGILState_Ensure` was called, and must be passed to
.. index:: single: setcheckinterval() (in module sys)
-Every check interval, when the interpreter lock is released and reacquired,
-python will also call any such provided functions. This can be used for
-example by asynchronous IO handlers. The notification can be scheduled
-from a worker thread and the actual call than made at the earliest
-convenience by the main thread where it has possession of the global
-interpreter lock and can perform any Python API calls.
+Every check interval, when the global interpreter lock is released and
+reacquired, python will also call any such provided functions. This can be used
+for example by asynchronous IO handlers. The notification can be scheduled from
+a worker thread and the actual call than made at the earliest convenience by the
+main thread where it has possession of the global interpreter lock and can
+perform any Python API calls.
.. cfunction:: void Py_AddPendingCall( int (*func)(void *, void *arg) )
.. index:: single: Py_AddPendingCall()
- Post a notification to the Python main thread. If successful,
- *func* will be called with the argument *arg* at the earliest
- convenience. *func* will be called having the global interpreter
- lock held and can thus use the full Python API and can take any
- action such as setting object attributes to signal IO completion.
- It must return 0 on success, or -1 signalling an exception.
- The notification function won't be interrupted to perform another
- asynchronous notification recursively,
- but it can still be interrupted to switch threads if the interpreter
- lock is released, for example, if it calls back into python code.
+ Post a notification to the Python main thread. If successful, *func* will be
+ called with the argument *arg* at the earliest convenience. *func* will be
+ called having the global interpreter lock held and can thus use the full
+ Python API and can take any action such as setting object attributes to
+ signal IO completion. It must return 0 on success, or -1 signalling an
+ exception. The notification function won't be interrupted to perform another
+ asynchronous notification recursively, but it can still be interrupted to
+ switch threads if the global interpreter lock is released, for example, if it
+ calls back into python code.
This function returns 0 on success in which case the notification has been
- scheduled. Otherwise, for example if the notification buffer is full,
- it returns -1 without setting any exception.
+ scheduled. Otherwise, for example if the notification buffer is full, it
+ returns -1 without setting any exception.
- This function can be called on any thread, be it a Python thread or
- some other system thread. If it is a Python thread, it doesn't matter if
- it holds the global interpreter lock or not.
+ This function can be called on any thread, be it a Python thread or some
+ other system thread. If it is a Python thread, it doesn't matter if it holds
+ the global interpreter lock or not.
.. versionadded:: 2.7
There are still some other options which can be used to handle special cases.
-The :option:`optional` option is a boolean; if it is true, that specifies that
-a build failure in the extension should not abort the build process, but simply
-not install the failing extension.
+The :option:`optional` option is a boolean; if it is true,
+a build failure in the extension will not abort the build process, but
+instead simply not install the failing extension.
The :option:`extra_objects` option is a list of object files to be passed to the
linker. These files must not have extensions, as the default extension for the
set SVNROOT=http://svn.python.org/projects\r
if "%PYTHON%" EQU "" set PYTHON=..\pcbuild\python\r
if "%HTMLHELP%" EQU "" set HTMLHELP=%ProgramFiles%\HTML Help Workshop\hhc.exe\r
+if "%DISTVERSION%" EQU "" for /f "usebackq" %%v in (`%PYTHON% tools/sphinxext/patchlevel.py`) do set DISTVERSION=%%v\r
\r
if "%1" EQU "" goto help\r
if "%1" EQU "html" goto build\r
if not exist build\doctrees mkdir build\doctrees\r
cmd /C %PYTHON% --version\r
cmd /C %PYTHON% tools\sphinx-build.py -b%1 -dbuild\doctrees . build\%*\r
-if "%1" EQU "htmlhelp" "%HTMLHELP%" build\htmlhelp\pydoc.hhp\r
+if "%1" EQU "htmlhelp" "%HTMLHELP%" build\htmlhelp\python%DISTVERSION:.=%.hhp\r
goto end\r
\r
:end\r
library/httplib,,:port,host:port
library/imaplib,,:MM,"""DD-Mmm-YYYY HH:MM:SS +HHMM"""
library/imaplib,,:SS,"""DD-Mmm-YYYY HH:MM:SS +HHMM"""
+library/itertools,,:stop,elements from seq[start:stop:step]
+library/itertools,,:step,elements from seq[start:stop:step]
library/linecache,,:sys,"sys:x:3:3:sys:/dev:/bin/sh"
library/logging,,:And,
library/logging,,:package1,
i = lnum - index
for line in lines:
num = small(' ' * (5-len(str(i))) + str(i)) + ' '
- line = '<tt>%s%s</tt>' % (num, pydoc.html.preformat(line))
if i in highlight:
+ line = '<tt>=>%s%s</tt>' % (num, pydoc.html.preformat(line))
rows.append('<tr><td bgcolor="#ffccee">%s</td></tr>' % line)
else:
+ line = '<tt> %s%s</tt>' % (num, pydoc.html.preformat(line))
rows.append('<tr><td>%s</td></tr>' % grey(line))
i += 1
-"""plistlib.py -- a tool to generate and parse MacOSX .plist files.
+r"""plistlib.py -- a tool to generate and parse MacOSX .plist files.
The PropertList (.plist) file format is a simple XML pickle supporting
basic object types, like dictionaries, lists, numbers and strings.
userhome = pwent.pw_dir
if isinstance(path, bytes):
userhome = userhome.encode(sys.getfilesystemencoding())
- userhome = userhome.rstrip(sep)
+ root = b'/'
+ else:
+ root = '/'
+ userhome = userhome.rstrip(root) or userhome
return userhome + path[i:]
except ImportError:
EBADF = 9
-__all__ = ["getfqdn"]
+__all__ = ["getfqdn", "create_connection"]
__all__.extend(os._get_exports_list(_socket))
m.move(source, dest, size)
except ValueError:
pass
- self.assertRaises(ValueError, m.move, -1, -1, -1)
- self.assertRaises(ValueError, m.move, -1, -1, 0)
- self.assertRaises(ValueError, m.move, -1, 0, -1)
- self.assertRaises(ValueError, m.move, 0, -1, -1)
- self.assertRaises(ValueError, m.move, -1, 0, 0)
- self.assertRaises(ValueError, m.move, 0, -1, 0)
- self.assertRaises(ValueError, m.move, 0, 0, -1)
+
+ offsets = [(-1, -1, -1), (-1, -1, 0), (-1, 0, -1), (0, -1, -1),
+ (-1, 0, 0), (0, -1, 0), (0, 0, -1)]
+ for source, dest, size in offsets:
+ self.assertRaises(ValueError, m.move, source, dest, size)
+
m.close()
+ m = mmap.mmap(-1, 1) # single byte
+ self.assertRaises(ValueError, m.move, 0, 0, 2)
+ self.assertRaises(ValueError, m.move, 1, 0, 1)
+ self.assertRaises(ValueError, m.move, 0, 1, 1)
+ m.move(0, 0, 1)
+ m.move(0, 0, 0)
+
+
def test_anonymous(self):
# anonymous mmap.mmap(-1, PAGE)
m = mmap.mmap(-1, PAGESIZE)
class Win32ErrorTests(unittest.TestCase):
pass
+ class PosixUidGidTests(unittest.TestCase):
+ if hasattr(os, 'setuid'):
+ def test_setuid(self):
+ if os.getuid() != 0:
+ self.assertRaises(os.error, os.setuid, 0)
+ self.assertRaises(OverflowError, os.setuid, 1<<32)
+
+ if hasattr(os, 'setgid'):
+ def test_setgid(self):
+ if os.getuid() != 0:
+ self.assertRaises(os.error, os.setgid, 0)
+ self.assertRaises(OverflowError, os.setgid, 1<<32)
+
+ if hasattr(os, 'seteuid'):
+ def test_seteuid(self):
+ if os.getuid() != 0:
+ self.assertRaises(os.error, os.seteuid, 0)
+ self.assertRaises(OverflowError, os.seteuid, 1<<32)
+
+ if hasattr(os, 'setegid'):
+ def test_setegid(self):
+ if os.getuid() != 0:
+ self.assertRaises(os.error, os.setegid, 0)
+ self.assertRaises(OverflowError, os.setegid, 1<<32)
+
+ if hasattr(os, 'setreuid'):
+ def test_setreuid(self):
+ if os.getuid() != 0:
+ self.assertRaises(os.error, os.setreuid, 0, 0)
+ self.assertRaises(OverflowError, os.setreuid, 1<<32, 0)
+ self.assertRaises(OverflowError, os.setreuid, 0, 1<<32)
+
+ if hasattr(os, 'setregid'):
+ def test_setregid(self):
+ if os.getuid() != 0:
+ self.assertRaises(os.error, os.setregid, 0, 0)
+ self.assertRaises(OverflowError, os.setregid, 1<<32, 0)
+ self.assertRaises(OverflowError, os.setregid, 0, 1<<32)
+else:
+ class PosixUidGidTests(unittest.TestCase):
+ pass
+
def test_main():
support.run_unittest(
FileTests,
URandomTests,
ExecTests,
Win32ErrorTests,
- TestInvalidFD
+ TestInvalidFD,
+ PosixUidGidTests
)
if __name__ == "__main__":
self.assert_(isinstance(posixpath.expanduser(b"~root/"), bytes))
self.assert_(isinstance(posixpath.expanduser(b"~foo/"), bytes))
+ orig_home = os.environ['HOME']
+ os.environ['HOME'] = '/'
+ self.assertEqual(posixpath.expanduser("~"), "/")
+ os.environ['HOME'] = orig_home
+
self.assertRaises(TypeError, posixpath.expanduser)
def test_expandvars(self):
self.assertEqual(len(sys.int_info), 2)
self.assert_(sys.int_info.bits_per_digit % 5 == 0)
self.assert_(sys.int_info.sizeof_digit >= 1)
+ self.assertEqual(type(sys.int_info.bits_per_digit), int)
+ self.assertEqual(type(sys.int_info.sizeof_digit), int)
self.assert_(isinstance(sys.hexversion, int))
self.assert_(isinstance(sys.maxsize, int))
self.assert_(isinstance(sys.maxunicode, int))
check(1, size(vh) + self.longdigit)
check(-1, size(vh) + self.longdigit)
PyLong_BASE = 2**sys.int_info.bits_per_digit
- check(PyLong_BASE, size(vh) + 2*self.longdigit)
- check(PyLong_BASE**2-1, size(vh) + 2*self.longdigit)
- check(PyLong_BASE**2, size(vh) + 3*self.longdigit)
+ check(int(PyLong_BASE), size(vh) + 2*self.longdigit)
+ check(int(PyLong_BASE**2-1), size(vh) + 2*self.longdigit)
+ check(int(PyLong_BASE**2), size(vh) + 3*self.longdigit)
# memory
check(memoryview(b''), size(h + 'P PP2P2i7P'))
# module
static PyObject *
mmap_move_method(mmap_object *self, PyObject *args)
{
- unsigned long dest, src, count;
+ unsigned long dest, src, cnt;
CHECK_VALID(NULL);
- if (!PyArg_ParseTuple(args, "kkk:move", &dest, &src, &count) ||
+ if (!PyArg_ParseTuple(args, "kkk:move", &dest, &src, &cnt) ||
!is_writable(self)) {
return NULL;
} else {
/* bounds check the values */
- unsigned long pos = src > dest ? src : dest;
- if (self->size < pos || count > self->size - pos) {
+ if (cnt < 0 || (cnt + dest) < cnt || (cnt + src) < cnt ||
+ src < 0 || src > self->size || (src + cnt) > self->size ||
+ dest < 0 || dest > self->size || (dest + cnt) > self->size) {
PyErr_SetString(PyExc_ValueError,
- "source or destination out of range");
+ "source, destination, or count out of range");
return NULL;
- } else {
- memmove(self->data+dest, self->data+src, count);
- Py_INCREF(Py_None);
- return Py_None;
}
+ memmove(self->data+dest, self->data+src, cnt);
+ Py_INCREF(Py_None);
+ return Py_None;
}
}
static PyObject *
posix_setuid(PyObject *self, PyObject *args)
{
- int uid;
- if (!PyArg_ParseTuple(args, "i:setuid", &uid))
+ long uid_arg;
+ uid_t uid;
+ if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
return NULL;
+ uid = uid_arg;
+ if (uid != uid_arg) {
+ PyErr_SetString(PyExc_OverflowError, "user id too big");
+ return NULL;
+ }
if (setuid(uid) < 0)
return posix_error();
Py_INCREF(Py_None);
static PyObject *
posix_seteuid (PyObject *self, PyObject *args)
{
- int euid;
- if (!PyArg_ParseTuple(args, "i", &euid)) {
+ long euid_arg;
+ uid_t euid;
+ if (!PyArg_ParseTuple(args, "l", &euid_arg))
+ return NULL;
+ euid = euid_arg;
+ if (euid != euid_arg) {
+ PyErr_SetString(PyExc_OverflowError, "user id too big");
return NULL;
- } else if (seteuid(euid) < 0) {
+ }
+ if (seteuid(euid) < 0) {
return posix_error();
} else {
Py_INCREF(Py_None);
static PyObject *
posix_setegid (PyObject *self, PyObject *args)
{
- int egid;
- if (!PyArg_ParseTuple(args, "i", &egid)) {
+ long egid_arg;
+ gid_t egid;
+ if (!PyArg_ParseTuple(args, "l", &egid_arg))
+ return NULL;
+ egid = egid_arg;
+ if (egid != egid_arg) {
+ PyErr_SetString(PyExc_OverflowError, "group id too big");
return NULL;
- } else if (setegid(egid) < 0) {
+ }
+ if (setegid(egid) < 0) {
return posix_error();
} else {
Py_INCREF(Py_None);
static PyObject *
posix_setreuid (PyObject *self, PyObject *args)
{
- int ruid, euid;
- if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
+ long ruid_arg, euid_arg;
+ uid_t ruid, euid;
+ if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
return NULL;
- } else if (setreuid(ruid, euid) < 0) {
+ ruid = ruid_arg;
+ euid = euid_arg;
+ if (euid != euid_arg || ruid != ruid_arg) {
+ PyErr_SetString(PyExc_OverflowError, "user id too big");
+ return NULL;
+ }
+ if (setreuid(ruid, euid) < 0) {
return posix_error();
} else {
Py_INCREF(Py_None);
static PyObject *
posix_setregid (PyObject *self, PyObject *args)
{
- int rgid, egid;
- if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
+ long rgid_arg, egid_arg;
+ gid_t rgid, egid;
+ if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
+ return NULL;
+ rgid = rgid_arg;
+ egid = egid_arg;
+ if (egid != egid_arg || rgid != rgid_arg) {
+ PyErr_SetString(PyExc_OverflowError, "group id too big");
return NULL;
- } else if (setregid(rgid, egid) < 0) {
+ }
+ if (setregid(rgid, egid) < 0) {
return posix_error();
} else {
Py_INCREF(Py_None);
static PyObject *
posix_setgid(PyObject *self, PyObject *args)
{
- int gid;
- if (!PyArg_ParseTuple(args, "i:setgid", &gid))
+ long gid_arg;
+ gid_t gid;
+ if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
+ return NULL;
+ gid = gid_arg;
+ if (gid != gid_arg) {
+ PyErr_SetString(PyExc_OverflowError, "group id too big");
return NULL;
+ }
if (setgid(gid) < 0)
return posix_error();
Py_INCREF(Py_None);
{
if (self->ob_exports > 0) {
PyErr_SetString(PyExc_SystemError,
- "deallocated bytearray object has exported buffers");
+ "deallocated bytearray object has exported buffers");
PyErr_Print();
}
if (self->ob_bytes != 0) {
/* Try to determine the length of the argument. 32 is abitrary. */
buf_size = _PyObject_LengthHint(arg, 32);
- if (buf_size == -1) {
- Py_DECREF(it);
- return NULL;
- }
+ if (buf_size == -1) {
+ Py_DECREF(it);
+ return NULL;
+ }
bytes_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
if (bytes_obj == NULL)
static PyObject *
bytes_sizeof(PyByteArrayObject *self)
{
- Py_ssize_t res;
+ Py_ssize_t res;
- res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char);
- return PyLong_FromSsize_t(res);
+ res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char);
+ return PyLong_FromSsize_t(res);
}
static PySequenceMethods bytes_as_sequence = {
if ((Py_ssize_t)strlen(ptr) != size) {
Py_DECREF(s);
return converterr(
- "(encoded string without NULL bytes)",
+ "encoded string without NULL bytes",
arg, msgbuf, bufsize);
}
*buffer = PyMem_NEW(char, size + 1);