summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/library/sys.rst8
-rw-r--r--Misc/NEWS5
-rw-r--r--Objects/fileobject.c2
-rw-r--r--Python/pythonrun.c61
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``.
+
diff --git a/Misc/NEWS b/Misc/NEWS
index c79b531..f68ac90 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -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;
}