Commit af935e3b authored by Christian Heimes's avatar Christian Heimes

Stop Python code from instantiating a new stdprinter with sys.stderr.__class__()

Added some more methods and attributes to stdprinter to ease up debugging #1415 on Windows. It also makes the object more file like. Now it can be used as a working replacement for an io instance.
parent 32fbe599
......@@ -325,7 +325,10 @@ Py_UniversalNewlineFgets(char *buf, int n, FILE *stream, PyObject *fobj)
return buf;
}
/* **************************** std printer **************************** */
/* **************************** std printer ****************************
* The stdprinter is used during the boot strapping phase as a preliminary
* file like object for sys.stderr.
*/
typedef struct {
PyObject_HEAD
......@@ -347,6 +350,14 @@ stdprinter_new(PyTypeObject *type, PyObject *args, PyObject *kews)
return (PyObject *) self;
}
static int
fileio_init(PyObject *self, PyObject *args, PyObject *kwds)
{
PyErr_SetString(PyExc_TypeError,
"cannot create 'stderrprinter' instances");
return -1;
}
PyObject *
PyFile_NewStdPrinter(int fd)
{
......@@ -372,14 +383,17 @@ stdprinter_write(PyStdPrinter_Object *self, PyObject *args)
Py_ssize_t n;
if (self->fd < 0) {
PyErr_SetString(PyExc_ValueError,
"I/O operation on closed file");
return NULL;
/* fd might be invalid on Windows
* I can't raise an exception here. It may lead to an
* unlimited recursion in the case stderr is invalid.
*/
return PyLong_FromLong((long)-1);
}
if (!PyArg_ParseTuple(args, "s#", &c, &n)) {
if (!PyArg_ParseTuple(args, "s", &c)) {
return NULL;
}
n = strlen(c);
Py_BEGIN_ALLOW_THREADS
errno = 0;
......@@ -393,12 +407,77 @@ stdprinter_write(PyStdPrinter_Object *self, PyObject *args)
return NULL;
}
return PyInt_FromSsize_t(n);
return PyLong_FromSsize_t(n);
}
static PyObject *
stdprinter_fileno(PyStdPrinter_Object *self)
{
return PyInt_FromLong((long) self->fd);
}
static PyObject *
stdprinter_repr(PyStdPrinter_Object *self)
{
return PyUnicode_FromFormat("<stdprinter(fd=%d) object at 0x%x>",
self->fd, self);
}
static PyObject *
stdprinter_noop(PyStdPrinter_Object *self)
{
Py_RETURN_NONE;
}
static PyObject *
stdprinter_isatty(PyStdPrinter_Object *self)
{
long res;
if (self->fd < 0) {
Py_INCREF(Py_False);
return Py_False;
}
Py_BEGIN_ALLOW_THREADS
res = isatty(self->fd);
Py_END_ALLOW_THREADS
return PyBool_FromLong(res);
}
static PyMethodDef stdprinter_methods[] = {
{"write", (PyCFunction)stdprinter_write, METH_VARARGS, ""},
{NULL, NULL} /* sentinel */
{"close", (PyCFunction)stdprinter_noop, METH_NOARGS, ""},
{"flush", (PyCFunction)stdprinter_noop, METH_NOARGS, ""},
{"fileno", (PyCFunction)stdprinter_fileno, METH_NOARGS, ""},
{"isatty", (PyCFunction)stdprinter_isatty, METH_NOARGS, ""},
{"write", (PyCFunction)stdprinter_write, METH_VARARGS, ""},
{NULL, NULL} /*sentinel */
};
static PyObject *
get_closed(PyStdPrinter_Object *self, void *closure)
{
Py_INCREF(Py_False);
return Py_False;
}
static PyObject *
get_mode(PyStdPrinter_Object *self, void *closure)
{
return PyUnicode_FromString("w");
}
static PyObject *
get_encoding(PyStdPrinter_Object *self, void *closure)
{
Py_RETURN_NONE;
}
static PyGetSetDef stdprinter_getsetlist[] = {
{"closed", (getter)get_closed, NULL, "True if the file is closed"},
{"encoding", (getter)get_encoding, NULL, "Encoding of the file"},
{"mode", (getter)get_mode, NULL, "String giving the file mode"},
{0},
};
PyTypeObject PyStdPrinter_Type = {
......@@ -412,7 +491,7 @@ PyTypeObject PyStdPrinter_Type = {
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
(reprfunc)stdprinter_repr, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
......@@ -432,13 +511,13 @@ PyTypeObject PyStdPrinter_Type = {
0, /* tp_iternext */
stdprinter_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
stdprinter_getsetlist, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
fileio_init, /* tp_init */
PyType_GenericAlloc, /* tp_alloc */
stdprinter_new, /* tp_new */
PyObject_Del, /* tp_free */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment