[Python-3000-checkins] r58948 - python/branches/py3k/Objects/fileobject.c

christian.heimes python-3000-checkins at python.org
Mon Nov 12 17:05:45 CET 2007


Author: christian.heimes
Date: Mon Nov 12 17:05:45 2007
New Revision: 58948

Modified:
   python/branches/py3k/Objects/fileobject.c
Log:
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.

Modified: python/branches/py3k/Objects/fileobject.c
==============================================================================
--- python/branches/py3k/Objects/fileobject.c	(original)
+++ python/branches/py3k/Objects/fileobject.c	Mon Nov 12 17:05:45 2007
@@ -325,7 +325,10 @@
 	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 @@
 	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 @@
 	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 @@
 		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 @@
 	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 @@
 	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 */


More information about the Python-3000-checkins mailing list