Index: Python/pythonrun.c =================================================================== --- Python/pythonrun.c (revision 58695) +++ Python/pythonrun.c (working copy) @@ -151,7 +151,7 @@ { PyInterpreterState *interp; PyThreadState *tstate; - PyObject *bimod, *sysmod; + PyObject *bimod, *sysmod, *stderr; char *p; #if defined(HAVE_LANGINFO_H) && defined(CODESET) char *codeset; @@ -228,6 +228,13 @@ PyDict_SetItemString(interp->sysdict, "modules", interp->modules); + /* set up a dump stderr printer until we have enough infrastructure + for the io module in place */ + stderr = _PyStderrPrinter_New(); + if (stderr == NULL) + Py_FatalError("Py_Initialize: can't set preliminary stderr"); + PySys_SetObject("stderr", stderr); + _PyImport_Init(); /* initialize builtin exceptions */ @@ -736,6 +743,9 @@ PySys_SetObject("stdout", std); Py_DECREF(std); + /* Remove old stderr printer */ + PySys_SetObject("stderr", NULL); + /* Set sys.stderr */ if (!(std = PyFile_FromFd(fileno(stderr), "", "w", -1, NULL, "\n"))) { Index: Include/fileobject.h =================================================================== --- Include/fileobject.h (revision 58695) +++ Include/fileobject.h (working copy) @@ -8,6 +8,13 @@ #define PY_STDIOTEXTMODE "b" +typedef struct { + PyObject_HEAD +} _PyStderrPrinter_Object; + +PyAPI_DATA(PyTypeObject) _PyStderrPrinter_Type; +PyAPI_FUNC(PyObject *) _PyStderrPrinter_New(void); + PyAPI_FUNC(PyObject *) PyFile_FromFd(int, char *, char *, int, char *, char *); PyAPI_FUNC(PyObject *) PyFile_GetLine(PyObject *, int); PyAPI_FUNC(int) PyFile_WriteObject(PyObject *, PyObject *, int); Index: Objects/object.c =================================================================== --- Objects/object.c (revision 58695) +++ Objects/object.c (working copy) @@ -1595,6 +1595,9 @@ if (PyType_Ready(&PyCode_Type) < 0) Py_FatalError("Can't initialize 'code'"); + + if (PyType_Ready(&_PyStderrPrinter_Type) < 0) + Py_FatalError("Can't initialize StderrPrinter"); } Index: Objects/fileobject.c =================================================================== --- Objects/fileobject.c (revision 58695) +++ Objects/fileobject.c (working copy) @@ -325,6 +325,92 @@ return buf; } +/* ************************* stderr printer ******************************** */ + +PyObject * +_PyStderrPrinter_New(void) +{ + PyObject *self; + self = (PyObject*)PyObject_New(_PyStderrPrinter_Object, + &_PyStderrPrinter_Type); + return self; +} + +PyDoc_STRVAR(stderrprinter_write_doc, +"write to stderr"); + +PyObject * +stderrprinter_write(PyObject *self, PyObject *args) +{ + PyObject *d; + char *c = NULL; + + if (!PyArg_ParseTuple(args, "O:write", &d)) + return NULL; + + if (PyBytes_Check(d)) { + c = PyBytes_AS_STRING(d); + } + else if (PyString_Check(d)) { + c = PyString_AS_STRING(d); + } else if (PyUnicode_Check(d)) { + c = PyUnicode_AsString(d); + } else { + PyErr_SetString(PyExc_TypeError, "invalid type"); + return NULL; + } + + if (c == NULL) { + PyErr_SetString(PyExc_ValueError, "no string"); + return NULL; + } + + fprintf(stderr, "%s", c); + fflush(stderr); + + Py_RETURN_NONE; +} + +static PyMethodDef stderrprinter_methods[] = { + {"write", (PyCFunction)stderrprinter_write, METH_VARARGS, + stderrprinter_write_doc}, + {NULL, NULL} /* sentinel */ +}; + +PyTypeObject _PyStderrPrinter_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "stderrprinter", /* tp_name */ + 0, /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + stderrprinter_methods, /* tp_methods */ + 0, +}; + + #ifdef __cplusplus } #endif