Christian Heimes added the comment:
I've carefully checked and tested the initstdio() method. I'm sure that
I've catched every edged case. The unit tests pass w/o complains.
I've also added a PyErr_Display() call to Py_FatalError(). It's still
hard to understand an error in io.py but at least the dependency on
site.py is removed.
__________________________________
Tracker <[EMAIL PROTECTED]>
<http://bugs.python.org/issue1267>
__________________________________
Index: Python/pythonrun.c
===================================================================
--- Python/pythonrun.c (revision 58477)
+++ Python/pythonrun.c (working copy)
@@ -51,6 +51,7 @@
/* Forward */
static void initmain(void);
static void initsite(void);
+static int initstdio(void);
static PyObject *run_mod(mod_ty, const char *, PyObject *, PyObject *,
PyCompilerFlags *, PyArena *);
static PyObject *run_pyc_file(FILE *, const char *, PyObject *, PyObject *,
@@ -241,8 +242,12 @@
initsigs(); /* Signal handling stuff, including initintr() */
initmain(); /* Module __main__ */
+ if (initstdio() < 0)
+ Py_FatalError("Py_Initialize: can't initialize sys standard"
+ "streams");
if (!Py_NoSiteFlag)
initsite(); /* Module site */
+
/* auto-thread-state API, if available */
#ifdef WITH_THREAD
@@ -676,6 +681,103 @@
}
}
+/* Initialize sys.stdin, stdout, stderr and __builtins__.open */
+static int
+initstdio(void)
+{
+ PyObject *iomod=NULL, *open, *wrapper;
+ PyObject *bimod=NULL;
+ PyObject *m;
+ PyObject *std=NULL, *args=NULL, *kwargs=NULL;
+ int status = 0;
+
+ /* Hack to avoid a nasty recursion issue when Python is invoked
+ in verbose mode: pre-import the Latin-1 and UTF-8 codecs */
+ if ((m = PyImport_ImportModule("encodings.utf_8")) == NULL) {
+ goto error;
+ }
+ Py_DECREF(m);
+
+ if (!(m = PyImport_ImportModule("encodings.latin_1"))) {
+ goto error;
+ }
+ Py_DECREF(m);
+
+ if (!(bimod = PyImport_ImportModule("__builtin__"))) {
+ goto error;
+ }
+
+ if (!(iomod = PyImport_ImportModule("io"))) {
+ goto error;
+ }
+ if (!(wrapper = PyObject_GetAttrString(iomod, "OpenWrapper"))) {
+ goto error;
+ }
+ if (!(open = PyObject_GetAttrString(iomod, "open"))) {
+ goto error;
+ }
+
+ if (PyObject_SetAttrString(bimod, "open", wrapper) == -1) {
+ goto error;
+ }
+
+ /* Add __builtin__.open */
+ if (!(kwargs = PyDict_New())) {
+ goto error;
+ }
+ if (PyDict_SetItemString(kwargs, "newline", PyString_FromString("\n"))
+ == -1) {
+ goto error;
+ }
+
+ /* Set sys.stdin */
+ if (!(args = Py_BuildValue("(is)", 0, "r"))) {
+ goto error;
+ }
+ if (!(std = PyObject_Call(open, args, kwargs))) {
+ goto error;
+ }
+ PySys_SetObject("__stdin__", std);
+ PySys_SetObject("stdin", std);
+ Py_DECREF(std);
+ Py_DECREF(args);
+
+ /* Set sys.stdout */
+ if (!(args = Py_BuildValue("(is)", 1, "w"))) {
+ goto error;
+ }
+ if (!(std = PyObject_Call(open, args, kwargs))) {
+ goto error;
+ }
+ PySys_SetObject("__stdout__", std);
+ PySys_SetObject("stdout", std);
+ Py_DECREF(std);
+ Py_DECREF(args);
+
+ /* Set sys.stderr */
+ if (!(args = Py_BuildValue("(is)", 2, "w"))) {
+ goto error;
+ }
+ if (!(std = PyObject_Call(open, args, kwargs))) {
+ goto error;
+ }
+ PySys_SetObject("__stderr__", std);
+ PySys_SetObject("stderr", std);
+ Py_DECREF(std);
+ Py_DECREF(args);
+
+ goto finally;
+
+error:
+ status = -1;
+ Py_XDECREF(args);
+finally:
+ Py_XDECREF(kwargs);
+ Py_XDECREF(bimod);
+ Py_XDECREF(iomod);
+ return status;
+}
+
/* Parse input from a file and execute it */
int
@@ -1146,10 +1248,10 @@
int err = 0;
PyObject *f = PySys_GetObject("stderr");
Py_INCREF(value);
- if (f == NULL)
+ if (f == NULL) {
_PyObject_Dump(value);
- if (f == NULL)
fprintf(stderr, "lost sys.stderr\n");
+ }
else {
fflush(stdout);
if (tb && tb != Py_None)
@@ -1589,6 +1691,9 @@
Py_FatalError(const char *msg)
{
fprintf(stderr, "Fatal Python error: %s\n", msg);
+ if (PyErr_Occurred()) {
+ PyErr_Print();
+ }
#ifdef MS_WINDOWS
OutputDebugString("Fatal Python error: ");
OutputDebugString(msg);
Index: Lib/site.py
===================================================================
--- Lib/site.py (revision 58477)
+++ Lib/site.py (working copy)
@@ -402,23 +402,6 @@
(err.__class__.__name__, err))
-def installnewio():
- """Install new I/O library as default."""
- import io
- # Hack to avoid a nasty recursion issue when Python is invoked
- # in verbose mode: pre-import the Latin-1 and UTF-8 codecs
- from encodings import latin_1, utf_8
- # Trick so that open won't become a bound method when stored
- # as a class variable (as dumbdbm does)
- class open:
- def __new__(cls, *args, **kwds):
- return io.open(*args, **kwds)
- __builtin__.open = open
- sys.__stdin__ = sys.stdin = io.open(0, "r", newline='\n')
- sys.__stdout__ = sys.stdout = io.open(1, "w", newline='\n')
- sys.__stderr__ = sys.stderr = io.open(2, "w", newline='\n')
-
-
def main():
abs__file__()
paths_in_sys = removeduppaths()
@@ -433,7 +416,6 @@
sethelper()
aliasmbcs()
setencoding()
- installnewio()
execsitecustomize()
# Remove sys.setdefaultencoding() so that users cannot change the
# encoding after initialization. The test for presence is needed when
Index: Lib/io.py
===================================================================
--- Lib/io.py (revision 58477)
+++ Lib/io.py (working copy)
@@ -178,6 +178,16 @@
return text
+class OpenWrapper:
+ """Wrapper for __builtin__.open
+
+ Trick so that open won't become a bound method when stored
+ as a class variable (as dumbdbm does)
+ """
+ def __new__(cls, *args, **kwargs):
+ return open(*args, **kwargs)
+
+
class UnsupportedOperation(ValueError, IOError):
pass
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com