Patch 1352 (continued in issue 1329) by Christian Heimes.

Before sys.stderr is set to the proper thing, set it to a really simple
file-like object that can print tracebacks using direct file descriptor I/O.
This is handy for debugging.
This commit is contained in:
Guido van Rossum 2007-10-30 18:34:07 +00:00
parent 1cd5bd2a2e
commit 826d8973ac
4 changed files with 136 additions and 1 deletions

View File

@ -21,6 +21,13 @@ PyAPI_FUNC(char *) Py_UniversalNewlineFgets(char *, int, FILE*, PyObject *);
*/ */
PyAPI_DATA(const char *) Py_FileSystemDefaultEncoding; PyAPI_DATA(const char *) Py_FileSystemDefaultEncoding;
/* Internal API
The std printer acts as a preliminary sys.stderr until the new io
infrastructure is in place. */
PyAPI_FUNC(PyObject *) PyFile_NewStdPrinter(int);
PyAPI_DATA(PyTypeObject) PyStdPrinter_Type;
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -325,6 +325,124 @@ Py_UniversalNewlineFgets(char *buf, int n, FILE *stream, PyObject *fobj)
return buf; return buf;
} }
/* **************************** std printer **************************** */
typedef struct {
PyObject_HEAD
int fd;
} PyStdPrinter_Object;
static PyObject *
stdprinter_new(PyTypeObject *type, PyObject *args, PyObject *kews)
{
PyStdPrinter_Object *self;
assert(type != NULL && type->tp_alloc != NULL);
self = (PyStdPrinter_Object *) type->tp_alloc(type, 0);
if (self != NULL) {
self->fd = -1;
}
return (PyObject *) self;
}
PyObject *
PyFile_NewStdPrinter(int fd)
{
PyStdPrinter_Object *self;
if (fd != 1 && fd != 2) {
PyErr_BadInternalCall();
return NULL;
}
self = PyObject_New(PyStdPrinter_Object,
&PyStdPrinter_Type);
self->fd = fd;
return (PyObject*)self;
}
PyObject *
stdprinter_write(PyStdPrinter_Object *self, PyObject *args)
{
char *c;
Py_ssize_t n;
if (self->fd < 0) {
PyErr_SetString(PyExc_ValueError,
"I/O operation on closed file");
return NULL;
}
if (!PyArg_ParseTuple(args, "s#", &c, &n)) {
return NULL;
}
Py_BEGIN_ALLOW_THREADS
errno = 0;
n = write(self->fd, c, n);
Py_END_ALLOW_THREADS
if (n < 0) {
if (errno == EAGAIN)
Py_RETURN_NONE;
PyErr_SetFromErrno(PyExc_IOError);
return NULL;
}
return PyInt_FromSsize_t(n);
}
static PyMethodDef stdprinter_methods[] = {
{"write", (PyCFunction)stdprinter_write, METH_VARARGS, ""},
{NULL, NULL} /* sentinel */
};
PyTypeObject PyStdPrinter_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"stderrprinter", /* tp_name */
sizeof(PyStdPrinter_Object), /* 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, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
stdprinter_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
PyType_GenericAlloc, /* tp_alloc */
stdprinter_new, /* tp_new */
PyObject_Del, /* tp_free */
};
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -1595,6 +1595,9 @@ _Py_ReadyTypes(void)
if (PyType_Ready(&PyCode_Type) < 0) if (PyType_Ready(&PyCode_Type) < 0)
Py_FatalError("Can't initialize 'code'"); Py_FatalError("Can't initialize 'code'");
if (PyType_Ready(&PyStdPrinter_Type) < 0)
Py_FatalError("Can't initialize StdPrinter");
} }

View File

@ -151,7 +151,7 @@ Py_InitializeEx(int install_sigs)
{ {
PyInterpreterState *interp; PyInterpreterState *interp;
PyThreadState *tstate; PyThreadState *tstate;
PyObject *bimod, *sysmod; PyObject *bimod, *sysmod, *pstderr;
char *p; char *p;
#if defined(HAVE_LANGINFO_H) && defined(CODESET) #if defined(HAVE_LANGINFO_H) && defined(CODESET)
char *codeset; char *codeset;
@ -228,6 +228,13 @@ Py_InitializeEx(int install_sigs)
PyDict_SetItemString(interp->sysdict, "modules", PyDict_SetItemString(interp->sysdict, "modules",
interp->modules); interp->modules);
/* Set up a preliminary stderr printer until we have enough
infrastructure for the io module in place. */
pstderr = PyFile_NewStdPrinter(fileno(stderr));
if (pstderr == NULL)
Py_FatalError("Py_Initialize: can't set preliminary stderr");
PySys_SetObject("stderr", pstderr);
_PyImport_Init(); _PyImport_Init();
/* initialize builtin exceptions */ /* initialize builtin exceptions */