[Python-checkins] r67819 - in sandbox/trunk/io-c: _fileio.c _iobase.c _iomodule.h _textio.c io.c

amaury.forgeotdarc python-checkins at python.org
Wed Dec 17 02:12:16 CET 2008


Author: amaury.forgeotdarc
Date: Wed Dec 17 02:12:15 2008
New Revision: 67819
Log:
io-c: TextIOWrapper works for basic usage, stdin/stdout can use it.
Still missing: seek() and tell(),
and the IncrementalNewlineDecoder.
probably tons of bugs and memory leaks.
Modified:
 sandbox/trunk/io-c/_fileio.c
 sandbox/trunk/io-c/_iobase.c
 sandbox/trunk/io-c/_iomodule.h
 sandbox/trunk/io-c/_textio.c
 sandbox/trunk/io-c/io.c
Modified: sandbox/trunk/io-c/_fileio.c
==============================================================================
--- sandbox/trunk/io-c/_fileio.c	(original)
+++ sandbox/trunk/io-c/_fileio.c	Wed Dec 17 02:12:15 2008
@@ -91,7 +91,7 @@
 }
 
 static PyObject *
-fileio_new(PyTypeObject *type, PyObject *args, PyObject *kews)
+fileio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 {
 	PyFileIOObject *self;
 
Modified: sandbox/trunk/io-c/_iobase.c
==============================================================================
--- sandbox/trunk/io-c/_iobase.c	(original)
+++ sandbox/trunk/io-c/_iobase.c	Wed Dec 17 02:12:15 2008
@@ -71,7 +71,7 @@
 static PyObject *
 IOBase_tell(PyObject *self, PyObject *args)
 {
- return PyObject_CallMethod(self, "tell", "ii", 0, 1);
+ return PyObject_CallMethod(self, "seek", "ii", 0, 1);
 }
 
 PyDoc_STRVAR(IOBase_truncate_doc,
Modified: sandbox/trunk/io-c/_iomodule.h
==============================================================================
--- sandbox/trunk/io-c/_iomodule.h	(original)
+++ sandbox/trunk/io-c/_iomodule.h	Wed Dec 17 02:12:15 2008
@@ -11,6 +11,7 @@
 extern PyTypeObject PyBufferedWriter_Type;
 extern PyTypeObject PyBufferedRWPair_Type;
 extern PyTypeObject PyBufferedRandom_Type;
+extern PyTypeObject PyTextIOWrapper_Type;
 
 extern PyObject* _PyIOBase_checkReadable(PyObject *self, PyObject *unused);
 extern PyObject* _PyIOBase_checkWritable(PyObject *self, PyObject *unused);
Modified: sandbox/trunk/io-c/_textio.c
==============================================================================
--- sandbox/trunk/io-c/_textio.c	(original)
+++ sandbox/trunk/io-c/_textio.c	Wed Dec 17 02:12:15 2008
@@ -1,4 +1,5 @@
 #include "Python.h"
+#include "structmember.h"
 #include "_iomodule.h"
 
 extern PyObject *
@@ -72,8 +73,7 @@
 PyObject_HEAD
 Py_ssize_t chunk_size;
 PyObject *buffer;
- const char *encoding;
- const char *errors;
+ PyObject *encoding;
 PyObject *encoder;
 PyObject *decoder;
 PyObject *readnl;
@@ -93,8 +93,140 @@
 * next_input is the chunk of input bytes that comes next after the
 * snapshot point. We use this to reconstruct decoder states in tell().
 */
+
+ PyObject *weakreflist;
+ PyObject *dict;
 } PyTextIOWrapperObject;
 
+static int
+TextIOWrapper_init(PyTextIOWrapperObject *self, PyObject *args, PyObject *kwds)
+{
+ char *kwlist[] = {"buffer", "encoding", "errors",
+ "newline", "line_buffering",
+		 NULL};
+ PyObject *buffer;
+ char *encoding = NULL;
+ char *errors = NULL;
+ char *newline = NULL;
+ int line_buffering = 0;
+
+ PyObject *res;
+ int r;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|zzzi:fileio",
+				 kwlist, &buffer, &encoding, &errors,
+				 &newline, &line_buffering))
+	return -1;
+
+ if (newline && newline[0] != '0円'
+	&& !(newline[0] == '\n' && newline[1] == '0円')
+	&& !(newline[0] == '\r' && newline[1] == '0円')
+	&& !(newline[0] == '\r' && newline[1] == '\n' && newline[2] == '0円')) {
+	PyErr_Format(PyExc_ValueError,
+		 "illegal newline value: %s", newline);
+	return -1;
+ }
+
+ if (encoding == NULL) {
+	/* Try os.device_encoding(fileno) */
+	PyObject *os = PyImport_ImportModule("os");
+	if (os == NULL)
+	 return -1;
+	self->encoding = PyObject_CallMethod(
+	 os, "device_encoding", "N",
+	 PyObject_CallMethod(buffer, "fileno", NULL));
+	Py_DECREF(os);
+	/* Ignore any error */
+	/* XXX only AttributeError and UnsupportedOperation */
+	if (self->encoding == NULL)
+	 PyErr_Clear();
+	if (!PyUnicode_Check(self->encoding))
+	 Py_CLEAR(self->encoding);
+ }
+ if (encoding == NULL && self->encoding == NULL) {
+	/* try locale.getpreferredencoding() */
+	PyObject *locale = PyImport_ImportModule("locale");
+	if (locale == NULL) {
+	 self->encoding = PyUnicode_FromString("ascii");
+	}
+	else {
+	 self->encoding = PyObject_CallMethod(
+		locale, "getpreferredencoding", NULL);
+	 Py_DECREF(locale);
+	 if (self->encoding == NULL)
+		return -1;
+	 if (!PyUnicode_Check(self->encoding))
+		Py_CLEAR(self->encoding);
+	}
+ }
+ if (self->encoding != NULL)
+	encoding = _PyUnicode_AsString(self->encoding);
+
+ if (errors == NULL)
+	errors = "strict";
+
+ self->chunk_size = 8192;
+ self->readuniversal = (newline == NULL || newline[0] == '0円');
+ self->line_buffering = line_buffering;
+ self->readtranslate = (newline == NULL);
+ if (newline)
+	self->readnl = PyUnicode_FromString(newline);
+ self->writetranslate = (newline == NULL || newline[0] != '0円');
+ if (self->readuniversal) {
+	if (self->readnl)
+	 self->writenl = _PyUnicode_AsString(self->readnl);
+ }
+#ifdef MS_WINDOWS
+ else
+ self->writenl = "\r\n";
+#endif
+
+ /* Build the decoder object */
+ res = PyObject_CallMethod(buffer, "readable", NULL);
+ if (res == NULL)
+	goto error;
+ r = PyObject_IsTrue(res);
+ Py_DECREF(res);
+ if (r == -1)
+	goto error;
+ if (r == 1) {
+	self->decoder = PyCodec_IncrementalDecoder(
+ encoding, errors);
+	if (self->decoder == NULL)
+	 goto error;
+
+ if (self->readuniversal) {
+ /* XXX
+ * decoder = IncrementalNewlineDecoder(decoder, self._readtranslate)
+ */
+ }
+ }
+
+ /* Build the encoder object */
+ res = PyObject_CallMethod(buffer, "writable", NULL);
+ if (res == NULL)
+	goto error;
+ r = PyObject_IsTrue(res);
+ Py_DECREF(res);
+ if (r == -1)
+	goto error;
+ if (r == 1) {
+	self->encoder = PyCodec_IncrementalEncoder(
+ encoding, errors);
+	if (self->encoder == NULL)
+	 goto error;
+ }
+
+ self->buffer = buffer;
+ Py_INCREF(buffer);
+
+ /* self._seekable = self._telling = self.buffer.seekable(); */
+ return 0;
+
+ error:
+ return -1;
+}
+
 Py_LOCAL_INLINE(const Py_UNICODE *)
 findchar(const Py_UNICODE *s, Py_ssize_t size, Py_UNICODE ch)
 {
@@ -108,47 +240,11 @@
 }
 
 static PyObject *
-TextIOWrapper_encoder_get(PyTextIOWrapperObject *self)
-{
- if (self->encoder == NULL) {
- self->encoder = PyCodec_IncrementalEncoder(
- self->encoding, self->errors);
-
- if (self->encoder == NULL)
- return NULL;
- }
-
- Py_INCREF(self->encoder);
- return self->encoder;
-}
-
-static PyObject *
-TextIOWrapper_decoder_get(PyTextIOWrapperObject *self)
-{
- if (self->decoder == NULL) {
- PyObject *decoder = PyCodec_IncrementalDecoder(
- self->encoding, self->errors);
-
- if (decoder == NULL)
- return NULL;
-
- if (self->readuniversal) {
- /* XXX
- * decoder = IncrementalNewlineDecoder(decoder, self._readtranslate)
- */
- }
- }
-
- Py_INCREF(self->decoder);
- return self->decoder;
-}
-
-static PyObject *
 TextIOWrapper_write(PyTextIOWrapperObject *self, PyObject *args)
 {
 PyObject *ret;
 PyObject *text; /* owned reference */
- PyObject *encoder, *b;
+ PyObject *b;
 Py_ssize_t textlen;
 int haslf = 0;
 int needflush = 0;
@@ -184,15 +280,9 @@
 PyUnicode_GET_SIZE(text), '\r')))
 needflush = 1;
 
- encoder = TextIOWrapper_encoder_get(self);
- if (!encoder) {
- Py_DECREF(text);
- return NULL;
- }
 /* XXX What if we were just reading? */
- b = PyObject_CallMethod(encoder, "encode", "O", text);
+ b = PyObject_CallMethod(self->encoder, "encode", "O", text);
 Py_DECREF(text);
- Py_DECREF(encoder);
 if (b == NULL)
 return NULL;
 
@@ -235,18 +325,20 @@
 TextIOWrapper_get_decoded_chars(PyTextIOWrapperObject *self, Py_ssize_t n)
 {
 PyObject *chars;
- Py_ssize_t avail = (PyBytes_GET_SIZE(self->decoded_chars)
- - self->decoded_chars_used);
+ Py_ssize_t avail;
 
 if (self->decoded_chars == NULL)
 return PyUnicode_FromStringAndSize(NULL, 0);
 
+ avail = (PyUnicode_GET_SIZE(self->decoded_chars)
+	 - self->decoded_chars_used);
+
 if (n < 0 || n > avail)
 n = avail;
 
- chars = PyBytes_FromStringAndSize(
- PyBytes_AS_STRING(self->decoded_chars) + self->decoded_chars_used,
- n);
+ chars = PyUnicode_FromUnicode(
+ PyUnicode_AS_UNICODE(self->decoded_chars)
+	+ self->decoded_chars_used, n);
 if (chars == NULL)
 return NULL;
 
@@ -357,23 +449,19 @@
 TextIOWrapper_read(PyTextIOWrapperObject *self, PyObject *args)
 {
 Py_ssize_t n = -1;
- PyObject *decoder;
 PyObject *result;
 
 if (!PyArg_ParseTuple(args, "|n:read", &n))
 return NULL;
 
- decoder = TextIOWrapper_decoder_get(self);
- if (decoder == NULL)
- return NULL;
-
 if (n < 0) {
 /* Read everything */
 PyObject *bytes = PyObject_CallMethod(self->buffer, "read", NULL);
 PyObject *decoded;
 if (bytes == NULL)
 goto fail;
- decoded = PyObject_CallMethod(decoder, "decode", "Oi", bytes, /*final=*/1);
+ decoded = PyObject_CallMethod(self->decoder, "decode",
+				 "Oi", bytes, /*final=*/1);
 
 if (self->decoded_chars) {
 result = PyNumber_Add(self->decoded_chars, decoded);
@@ -386,7 +474,6 @@
 result = decoded;
 }
 Py_CLEAR(self->snapshot);
- Py_DECREF(decoder);
 return result;
 }
 else {
@@ -410,11 +497,9 @@
 if (result == NULL)
 goto fail;
 }
- Py_DECREF(decoder);
 return result;
 }
 fail:
- Py_DECREF(decoder);
 return NULL;
 }
 
@@ -442,11 +527,11 @@
 TextIOWrapper_readline(PyTextIOWrapperObject *self, PyObject *args)
 {
 Py_ssize_t limit = -1;
- PyObject *line, *decoder;
+ PyObject *line;
 Py_ssize_t start, endpos;
 int res;
 
- if (!PyArg_ParseTuple(args, "n:readline", &limit)) {
+ if (!PyArg_ParseTuple(args, "|n:readline", &limit)) {
 return NULL;
 }
 
@@ -460,10 +545,6 @@
 
 start = 0;
 
- decoder = TextIOWrapper_decoder_get(self);
- if (decoder == NULL)
- goto error;
-
 endpos = -1;
 
 while (1) {
@@ -576,3 +657,79 @@
 Py_DECREF(line);
 return NULL;
 }
+
+static PyMethodDef TextIOWrapper_methods[] = {
+/* {"seekable", (PyCFunction)TextIOWrapper_seekable, METH_NOARGS},
+ {"readable", (PyCFunction)TextIOWrapper_readable, METH_NOARGS},
+ {"writable", (PyCFunction)TextIOWrapper_writable, METH_NOARGS},
+ {"fileno", (PyCFunction)TextIOWrapper_fileno, METH_NOARGS},
+ {"isatty", (PyCFunction)TextIOWrapper_isatty, METH_NOARGS},
+ {"flush", (PyCFunction)BufferedWriter_flush, METH_NOARGS},
+*/
+
+ {"write", (PyCFunction)TextIOWrapper_write, METH_VARARGS},
+ {"read", (PyCFunction)TextIOWrapper_read, METH_VARARGS},
+ {"readline", (PyCFunction)TextIOWrapper_readline, METH_VARARGS},
+/* {"seek", (PyCFunction)TextIOWrapper_seek, METH_VARARGS},
+ {"tell", (PyCFunction)TextIOWrapper_tell, METH_NOARGS},
+ {"truncate", (PyCFunction)TextIOWrapper_truncate, METH_VARARGS},
+ {"readinto", (PyCFunction)TextIOWrapper_readinto, METH_VARARGS},
+ {"peek", (PyCFunction)TextIOWrapper_peek, METH_VARARGS},
+ {"read1", (PyCFunction)TextIOWrapper_read1, METH_VARARGS},
+*/
+ {NULL, NULL}
+};
+
+static PyMemberDef TextIOWrapper_members[] = {
+ {"encoding", T_OBJECT, offsetof(PyTextIOWrapperObject, encoding), READONLY},
+ {NULL}
+};
+
+static PyGetSetDef TextIOWrapper_getset[] = {
+/* {"closed", (getter)TextIOWrapper_closed_get, NULL, NULL},
+ {"name", (getter)TextIOWrapper_name_get, NULL, NULL},
+ {"mode", (getter)TextIOWrapper_mode_get, NULL, NULL},
+*/
+ {0}
+};
+
+PyTypeObject PyTextIOWrapper_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "TextIOWrapper", /*tp_name*/
+ sizeof(PyTextIOWrapperObject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ 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*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ TextIOWrapper_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ offsetof(PyTextIOWrapperObject, weakreflist), /*tp_weaklistoffset*/
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ TextIOWrapper_methods, /* tp_methods */
+ TextIOWrapper_members, /* tp_members */
+ TextIOWrapper_getset, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ offsetof(PyTextIOWrapperObject, dict), /*tp_dictoffset*/
+ (initproc)TextIOWrapper_init, /* tp_init */
+ 0, /* tp_alloc */
+ PyType_GenericNew, /* tp_new */
+};
Modified: sandbox/trunk/io-c/io.c
==============================================================================
--- sandbox/trunk/io-c/io.c	(original)
+++ sandbox/trunk/io-c/io.c	Wed Dec 17 02:12:15 2008
@@ -3,9 +3,6 @@
 #include "_iomodule.h"
 
 PyObject *PyIOExc_UnsupportedOperation;
-
-
-static PyObject *io_py_module;
 
 
 PyDoc_STRVAR(module_doc,
@@ -434,7 +431,7 @@
 PyObject *Buffered_class;
 
 if (updating)
-	 Buffered_class = (PyObject *)&PyBufferedRandom_Type;
+ Buffered_class = (PyObject *)&PyBufferedRandom_Type;
 else if (writing || appending)
 Buffered_class = (PyObject *)&PyBufferedWriter_Type;
 else if (reading)
@@ -459,19 +456,11 @@
 }
 
 /* wraps into a TextIOWrapper */
- {
- PyObject *TextIOWrapper_class;
- TextIOWrapper_class = PyObject_GetAttrString(io_py_module,
- "TextIOWrapper");
- if (TextIOWrapper_class == NULL)
- goto error;
-
- wrapper = PyObject_CallFunction(TextIOWrapper_class, "Osssi",
- buffer,
- encoding, errors, newline,
- line_buffering);
- Py_DECREF(TextIOWrapper_class);
- }
+ wrapper = PyObject_CallFunction((PyObject *)&PyTextIOWrapper_Type,
+				 "Osssi",
+				 buffer,
+				 encoding, errors, newline,
+				 line_buffering);
 Py_CLEAR(buffer);
 if (wrapper == NULL)
 goto error;
@@ -519,10 +508,6 @@
 if (m == NULL)
 goto fail;
 
- io_py_module = PyImport_ImportModule("io");
- if (io_py_module == NULL)
- goto fail;
-
 /* UnsupportedOperation inherits from ValueError and IOError */
 PyIOExc_UnsupportedOperation = PyObject_CallFunction(
 (PyObject *)&PyType_Type, "s(OO){}",
@@ -601,6 +586,13 @@
 Py_INCREF(&PyBufferedRandom_Type);
 PyModule_AddObject(m, "BufferedRandom", (PyObject *) &PyBufferedRandom_Type);
 
+ /* TextIOWrapper */
+ PyTextIOWrapper_Type.tp_base = &PyIOBase_Type;
+ if (PyType_Ready(&PyTextIOWrapper_Type) < 0)
+ goto fail;
+ Py_INCREF(&PyTextIOWrapper_Type);
+ PyModule_AddObject(m, "TextIOWrapper", (PyObject *) &PyTextIOWrapper_Type);
+
 return m;
 
 fail:


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /