]> granicus.if.org Git - python/commitdiff
Fix for #1415 pythonw.exe fails because std streams a missing
authorChristian Heimes <christian@cheimes.de>
Tue, 13 Nov 2007 02:19:40 +0000 (02:19 +0000)
committerChristian Heimes <christian@cheimes.de>
Tue, 13 Nov 2007 02:19:40 +0000 (02:19 +0000)
After a long discussion about the problem with Windows GUI apps Guido decided that sys.stdin, stdout and stderr should be None when the C runtime library returns invalid file descriptors for the standard streams.

So far the only known cases are Windows GUI apps and scripts started with pythonw on Windows. The OS restrictions are tight enough to catch the problem on other OSes.

Doc/library/sys.rst
Misc/NEWS
Objects/fileobject.c
Python/pythonrun.c

index 6f1aaff87bb527e9df43397fe37ddf8131b86b70..94e4eb936ecfa38d5b16ce43d4b12580769f6a34 100644 (file)
@@ -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``.
 
+
index c79b53109ed292f8ed68822a3513b710675c23ef..f68ac904ae274ef34375dc2eeff2c5ae68f641b3 100644 (file)
--- 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
 -----------------
 
index 6d6022eedfdd0b87f00e41371bfb70fe0cb09bae..5d69911ff66e69f658c05f2473cae6b7f5833b38 100644 (file)
@@ -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;
        }
index 0b3935ab697382ee31be36fe0b73959a35b44831..82f8e373cafda531681f79c5d9fda2171b93d67a 100644 (file)
@@ -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;
         }