Core and Builtins
-----------------
-- Issue #8651: PyArg_Parse*() functions raise an OverflowError if the file
- doesn't have PY_SSIZE_T_CLEAN define and the size doesn't fit in an int
- (length bigger than 2^31-1 bytes).
+ - Issue #11650: PyOS_StdioReadline() retries fgets() if it was interrupted
+ (EINTR), for example if the program is stopped with CTRL+z on Mac OS X. Patch
+ written by Charles-Francois Natali.
+
+- Issue #11395: io.FileIO().write() clamps the data length to 32,767 bytes on
+ Windows if the file is a TTY to workaround a Windows bug. The Windows console
+ returns an error (12: not enough space error) on writing into stdout if
+ stdout mode is binary and the length is greater than 66,000 bytes (or less,
+ depending on heap usage).
+
+- Issue #11320: fix bogus memory management in Modules/getpath.c, leading to
+ a possible crash when calling Py_SetPath().
+
+- Issue #11510: Fixed optimizer bug which turned "a,b={1,1}" into "a,b=(1,1)".
+
+- Issue #11432: A bug was introduced in subprocess.Popen on posix systems with
+ 3.2.0 where the stdout or stderr file descriptor being the same as the stdin
+ file descriptor would raise an exception. webbrowser.open would fail. fixed.
- Issue #11450: Don't truncate hg version info in Py_GetBuildInfo() when
there are many tags (e.g. when using mq). Patch by Nadeem Vawda.
my_fgets(char *buf, int len, FILE *fp)
{
char *p;
- if (PyOS_InputHook != NULL)
- (void)(PyOS_InputHook)();
- errno = 0;
- p = fgets(buf, len, fp);
- if (p != NULL)
- return 0; /* No error */
+ while (1) {
+ if (PyOS_InputHook != NULL)
+ (void)(PyOS_InputHook)();
+ errno = 0;
+ p = fgets(buf, len, fp);
+ if (p != NULL)
+ return 0; /* No error */
#ifdef MS_WINDOWS
- /* In the case of a Ctrl+C or some other external event
- interrupting the operation:
- Win2k/NT: ERROR_OPERATION_ABORTED is the most recent Win32
- error code (and feof() returns TRUE).
- Win9x: Ctrl+C seems to have no effect on fgets() returning
- early - the signal handler is called, but the fgets()
- only returns "normally" (ie, when Enter hit or feof())
- */
- if (GetLastError()==ERROR_OPERATION_ABORTED) {
- /* Signals come asynchronously, so we sleep a brief
- moment before checking if the handler has been
- triggered (we cant just return 1 before the
- signal handler has been called, as the later
- signal may be treated as a separate interrupt).
+ /* In the case of a Ctrl+C or some other external event
+ interrupting the operation:
+ Win2k/NT: ERROR_OPERATION_ABORTED is the most recent Win32
+ error code (and feof() returns TRUE).
+ Win9x: Ctrl+C seems to have no effect on fgets() returning
+ early - the signal handler is called, but the fgets()
+ only returns "normally" (ie, when Enter hit or feof())
*/
- Sleep(1);
- if (PyOS_InterruptOccurred()) {
- return 1; /* Interrupt */
+ if (GetLastError()==ERROR_OPERATION_ABORTED) {
+ /* Signals come asynchronously, so we sleep a brief
+ moment before checking if the handler has been
+ triggered (we cant just return 1 before the
+ signal handler has been called, as the later
+ signal may be treated as a separate interrupt).
+ */
+ Sleep(1);
+ if (PyOS_InterruptOccurred()) {
+ return 1; /* Interrupt */
+ }
+ /* Either the sleep wasn't long enough (need a
+ short loop retrying?) or not interrupted at all
+ (in which case we should revisit the whole thing!)
+ Logging some warning would be nice. assert is not
+ viable as under the debugger, the various dialogs
+ mean the condition is not true.
+ */
}
- /* Either the sleep wasn't long enough (need a
- short loop retrying?) or not interrupted at all
- (in which case we should revisit the whole thing!)
- Logging some warning would be nice. assert is not
- viable as under the debugger, the various dialogs
- mean the condition is not true.
- */
- }
#endif /* MS_WINDOWS */
- if (feof(fp)) {
- return -1; /* EOF */
- }
+ if (feof(fp)) {
+ return -1; /* EOF */
+ }
#ifdef EINTR
- if (errno == EINTR) {
- int s;
+ if (errno == EINTR) {
+ int s;
#ifdef WITH_THREAD
- PyEval_RestoreThread(_PyOS_ReadlineTState);
+ PyEval_RestoreThread(_PyOS_ReadlineTState);
#endif
- s = PyErr_CheckSignals();
+ s = PyErr_CheckSignals();
#ifdef WITH_THREAD
- PyEval_SaveThread();
+ PyEval_SaveThread();
#endif
- if (s < 0) {
- return 1;
+ if (s < 0)
+ return 1;
- /* try again */
++ /* try again */
+ continue;
}
- }
#endif
- if (PyOS_InterruptOccurred()) {
- return 1; /* Interrupt */
+ if (PyOS_InterruptOccurred()) {
+ return 1; /* Interrupt */
+ }
+ return -2; /* Error */
}
- return -2; /* Error */
+ /* NOTREACHED */
}