mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +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;
|
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 {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
|
@ -347,6 +350,14 @@ stdprinter_new(PyTypeObject *type, PyObject *args, PyObject *kews)
|
||||||
return (PyObject *) self;
|
return (PyObject *) self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
fileio_init(PyObject *self, PyObject *args, PyObject *kwds)
|
||||||
|
{
|
||||||
|
PyErr_SetString(PyExc_TypeError,
|
||||||
|
"cannot create 'stderrprinter' instances");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyFile_NewStdPrinter(int fd)
|
PyFile_NewStdPrinter(int fd)
|
||||||
{
|
{
|
||||||
|
@ -372,14 +383,17 @@ stdprinter_write(PyStdPrinter_Object *self, PyObject *args)
|
||||||
Py_ssize_t n;
|
Py_ssize_t n;
|
||||||
|
|
||||||
if (self->fd < 0) {
|
if (self->fd < 0) {
|
||||||
PyErr_SetString(PyExc_ValueError,
|
/* fd might be invalid on Windows
|
||||||
"I/O operation on closed file");
|
* I can't raise an exception here. It may lead to an
|
||||||
return NULL;
|
* 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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
n = strlen(c);
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
@ -393,12 +407,77 @@ stdprinter_write(PyStdPrinter_Object *self, PyObject *args)
|
||||||
return NULL;
|
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[] = {
|
static PyMethodDef stdprinter_methods[] = {
|
||||||
{"write", (PyCFunction)stdprinter_write, METH_VARARGS, ""},
|
{"close", (PyCFunction)stdprinter_noop, METH_NOARGS, ""},
|
||||||
{NULL, NULL} /* sentinel */
|
{"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 = {
|
PyTypeObject PyStdPrinter_Type = {
|
||||||
|
@ -412,7 +491,7 @@ PyTypeObject PyStdPrinter_Type = {
|
||||||
0, /* tp_getattr */
|
0, /* tp_getattr */
|
||||||
0, /* tp_setattr */
|
0, /* tp_setattr */
|
||||||
0, /* tp_compare */
|
0, /* tp_compare */
|
||||||
0, /* tp_repr */
|
(reprfunc)stdprinter_repr, /* tp_repr */
|
||||||
0, /* tp_as_number */
|
0, /* tp_as_number */
|
||||||
0, /* tp_as_sequence */
|
0, /* tp_as_sequence */
|
||||||
0, /* tp_as_mapping */
|
0, /* tp_as_mapping */
|
||||||
|
@ -432,13 +511,13 @@ PyTypeObject PyStdPrinter_Type = {
|
||||||
0, /* tp_iternext */
|
0, /* tp_iternext */
|
||||||
stdprinter_methods, /* tp_methods */
|
stdprinter_methods, /* tp_methods */
|
||||||
0, /* tp_members */
|
0, /* tp_members */
|
||||||
0, /* tp_getset */
|
stdprinter_getsetlist, /* tp_getset */
|
||||||
0, /* tp_base */
|
0, /* tp_base */
|
||||||
0, /* tp_dict */
|
0, /* tp_dict */
|
||||||
0, /* tp_descr_get */
|
0, /* tp_descr_get */
|
||||||
0, /* tp_descr_set */
|
0, /* tp_descr_set */
|
||||||
0, /* tp_dictoffset */
|
0, /* tp_dictoffset */
|
||||||
0, /* tp_init */
|
fileio_init, /* tp_init */
|
||||||
PyType_GenericAlloc, /* tp_alloc */
|
PyType_GenericAlloc, /* tp_alloc */
|
||||||
stdprinter_new, /* tp_new */
|
stdprinter_new, /* tp_new */
|
||||||
PyObject_Del, /* tp_free */
|
PyObject_Del, /* tp_free */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue