]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Patch 1352 (continued in issue 1329) by Christian Heimes.
authorGuido van Rossum <guido@python.org>
Tue, 30 Oct 2007 18:34:07 +0000 (18:34 +0000)
committerGuido van Rossum <guido@python.org>
Tue, 30 Oct 2007 18:34:07 +0000 (18:34 +0000)
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.

Include/fileobject.h
Objects/fileobject.c
Objects/object.c
Python/pythonrun.c

index ae127da0c78df83498740c67bc54ba105023f7ac..40d871aea5df62b1b578e62d47b2c72fe91b6a6d 100644 (file)
@@ -21,6 +21,13 @@ PyAPI_FUNC(char *) Py_UniversalNewlineFgets(char *, int, FILE*, PyObject *);
 */
 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
 }
 #endif
index 4e18480b31279928d82b1e1949737194b890c950..dc0f1fd1473383375c3e41918ab94908b69a44d2 100644 (file)
@@ -325,6 +325,124 @@ Py_UniversalNewlineFgets(char *buf, int n, FILE *stream, PyObject *fobj)
        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
 }
 #endif
index f6d125f03c3ac636089901b2e02447f459009914..77ddb1d2713b74ff8632c64bf593409b97e36259 100644 (file)
@@ -1595,6 +1595,9 @@ _Py_ReadyTypes(void)
 
        if (PyType_Ready(&PyCode_Type) < 0)
                Py_FatalError("Can't initialize 'code'");
+
+       if (PyType_Ready(&PyStdPrinter_Type) < 0)
+               Py_FatalError("Can't initialize StdPrinter");
 }
 
 
index 76da8fb7f772ccccd3182509f8500cb628a3449a..ec9ed02ab9bd20abf9884ab6fe0fce3bfe8c075f 100644 (file)
@@ -151,7 +151,7 @@ Py_InitializeEx(int install_sigs)
 {
        PyInterpreterState *interp;
        PyThreadState *tstate;
-       PyObject *bimod, *sysmod;
+       PyObject *bimod, *sysmod, *pstderr;
        char *p;
 #if defined(HAVE_LANGINFO_H) && defined(CODESET)
        char *codeset;
@@ -228,6 +228,13 @@ Py_InitializeEx(int install_sigs)
        PyDict_SetItemString(interp->sysdict, "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();
 
        /* initialize builtin exceptions */