mirror of
https://github.com/python/cpython.git
synced 2025-08-04 08:59:19 +00:00
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.
This commit is contained in:
parent
32fbe59978
commit
af935e3bc4
1 changed files with 90 additions and 11 deletions
|
@ -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 */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue