diff options
-rw-r--r-- | Doc/library/sys.rst | 8 | ||||
-rw-r--r-- | Misc/NEWS | 5 | ||||
-rw-r--r-- | Objects/fileobject.c | 2 | ||||
-rw-r--r-- | Python/pythonrun.c | 61 |
4 files changed, 63 insertions, 13 deletions
diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index 6f1aaff..94e4eb9 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -513,6 +513,13 @@ always available. could be useful to restore the actual files to known working file objects in case they have been overwritten with a broken object. + .. note:: + + Under some conditions ``stdin``, ``stdout`` and ``stderr`` as well as the + original values ``__stdin__``, ``__stdout__`` and ``__stderr__`` can be + None. It is usually the case for Windows GUI apps that aren't connected to + a console and Python apps started with :program:`pythonw`. + .. data:: tracebacklimit @@ -571,3 +578,4 @@ always available. Module :mod:`site` This describes how to use .pth files to extend ``sys.path``. + @@ -34,6 +34,11 @@ Core and Builtins - Added a new option -b to issues warnings (-bb for errors) about certain operations between bytes/buffer and str like str(b'') and comparsion. +- The standards streams sys.stdin, stdout and stderr may be None when the + when the C runtime library returns an invalid file descriptor for the + streams (fileno(stdin) < 0). For now this happens only for Windows GUI + apps and scripts started with `pythonw.exe`. + Extension Modules ----------------- diff --git a/Objects/fileobject.c b/Objects/fileobject.c index 6d6022e..5d69911 100644 --- a/Objects/fileobject.c +++ b/Objects/fileobject.c @@ -363,7 +363,7 @@ PyFile_NewStdPrinter(int fd) { PyStdPrinter_Object *self; - if ((fd != fileno(stdout) && fd != fileno(stderr)) || fd < 0) { + if (fd != fileno(stdout) && fd != fileno(stderr)) { /* not enough infrastructure for PyErr_BadInternalCall() */ return NULL; } diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 0b3935a..82f8e37 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -717,7 +717,7 @@ initstdio(void) PyObject *bimod = NULL; PyObject *m; PyObject *std = NULL; - int status = 0; + int status = 0, fd; /* Hack to avoid a nasty recursion issue when Python is invoked in verbose mode: pre-import the Latin-1 and UTF-8 codecs */ @@ -748,35 +748,72 @@ initstdio(void) } /* Set sys.stdin */ - if (!(std = PyFile_FromFd(fileno(stdin), "<stdin>", "r", -1, - NULL, "\n", 0))) { + fd = fileno(stdin); + /* Under some conditions stdin, stdout and stderr may not be connected + * and fileno() may point to an invalid file descriptor. For example + * GUI apps don't have valid standard streams by default. + */ + if (fd < 0) { +#ifdef MS_WINDOWS + std = Py_None; + Py_INCREF(std); +#else goto error; +#endif } + else { + if (!(std = PyFile_FromFd(fd, "<stdin>", "r", -1, NULL, + "\n", 0))) { + goto error; + } + } /* if (fd < 0) */ PySys_SetObject("__stdin__", std); PySys_SetObject("stdin", std); Py_DECREF(std); /* Set sys.stdout */ - if (!(std = PyFile_FromFd(fileno(stdout), "<stdout>", "w", -1, - NULL, "\n", 0))) { - goto error; - } + fd = fileno(stdout); + if (fd < 0) { +#ifdef MS_WINDOWS + std = Py_None; + Py_INCREF(std); +#else + goto error; +#endif + } + else { + if (!(std = PyFile_FromFd(fd, "<stdout>", "w", -1, NULL, + "\n", 0))) { + goto error; + } + } /* if (fd < 0) */ PySys_SetObject("__stdout__", std); PySys_SetObject("stdout", std); Py_DECREF(std); #if 1 /* Disable this if you have trouble debugging bootstrap stuff */ /* Set sys.stderr, replaces the preliminary stderr */ - if (!(std = PyFile_FromFd(fileno(stderr), "<stderr>", "w", -1, - NULL, "\n", 0))) { - goto error; - } + fd = fileno(stderr); + if (fd < 0) { +#ifdef MS_WINDOWS + std = Py_None; + Py_INCREF(std); +#else + goto error; +#endif + } + else { + if (!(std = PyFile_FromFd(fd, "<stderr>", "w", -1, NULL, + "\n", 0))) { + goto error; + } + } /* if (fd < 0) */ PySys_SetObject("__stderr__", std); PySys_SetObject("stderr", std); Py_DECREF(std); #endif - if (0) { + if (0) { error: status = -1; } |