summaryrefslogtreecommitdiff
path: root/Modules/_io/iobase.c
diff options
context:
space:
mode:
authorGregory P. Smith <greg@krypto.org>2012-06-24 00:23:47 -0700
committerGregory P. Smith <greg@krypto.org>2012-06-24 00:23:47 -0700
commit359cfb35b929b3eaaabfe11ac6c4b01b1a20ee64 (patch)
tree0c512f578b733f1292adf2c4569678c874b63eea /Modules/_io/iobase.c
parent7d667d9f5142800a20754d7981e7adfa416b5ff6 (diff)
parent57cdc7d92b0950a10f282c10966c2c5717e2a091 (diff)
downloadcpython-359cfb35b929b3eaaabfe11ac6c4b01b1a20ee64.tar.gz
Fixes issue #12268: File readline, readlines and read() or readall() methods
no longer lose data when an underlying read system call is interrupted. IOError is no longer raised due to a read system call returning EINTR from within these methods.
Diffstat (limited to 'Modules/_io/iobase.c')
-rw-r--r--Modules/_io/iobase.c49
1 files changed, 24 insertions, 25 deletions
diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c
index 2bba1bfd58..dd052ae6e9 100644
--- a/Modules/_io/iobase.c
+++ b/Modules/_io/iobase.c
@@ -59,8 +59,9 @@ PyDoc_STRVAR(iobase_doc,
of the IOBase object rather than the virtual `closed` attribute as returned
by whatever subclass. */
+_Py_IDENTIFIER(__IOBase_closed);
#define IS_CLOSED(self) \
- PyObject_HasAttrString(self, "__IOBase_closed")
+ _PyObject_HasAttrId(self, &PyId___IOBase_closed)
/* Internal methods */
static PyObject *
@@ -97,7 +98,9 @@ PyDoc_STRVAR(iobase_tell_doc,
static PyObject *
iobase_tell(PyObject *self, PyObject *args)
{
- return PyObject_CallMethod(self, "seek", "ii", 0, 1);
+ _Py_IDENTIFIER(seek);
+
+ return _PyObject_CallMethodId(self, &PyId_seek, "ii", 0, 1);
}
PyDoc_STRVAR(iobase_truncate_doc,
@@ -156,19 +159,6 @@ iobase_closed_get(PyObject *self, void *context)
return PyBool_FromLong(IS_CLOSED(self));
}
-static PyObject *
-iobase_get_dict(PyObject *self)
-{
- PyObject **dictptr = _PyObject_GetDictPtr(self);
- PyObject *dict;
- assert(dictptr);
- dict = *dictptr;
- if (dict == NULL)
- dict = *dictptr = PyDict_New();
- Py_XINCREF(dict);
- return dict;
-}
-
PyObject *
_PyIOBase_check_closed(PyObject *self, PyObject *args)
{
@@ -190,12 +180,13 @@ static PyObject *
iobase_close(PyObject *self, PyObject *args)
{
PyObject *res;
+ _Py_IDENTIFIER(__IOBase_closed);
if (IS_CLOSED(self))
Py_RETURN_NONE;
res = PyObject_CallMethodObjArgs(self, _PyIO_str_flush, NULL);
- PyObject_SetAttrString(self, "__IOBase_closed", Py_True);
+ _PyObject_SetAttrId(self, &PyId___IOBase_closed, Py_True);
if (res == NULL) {
return NULL;
}
@@ -464,12 +455,14 @@ iobase_readline(PyObject *self, PyObject *args)
int has_peek = 0;
PyObject *buffer, *result;
Py_ssize_t old_size = -1;
+ _Py_IDENTIFIER(read);
+ _Py_IDENTIFIER(peek);
if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit)) {
return NULL;
}
- if (PyObject_HasAttrString(self, "peek"))
+ if (_PyObject_HasAttrId(self, &PyId_peek))
has_peek = 1;
buffer = PyByteArray_FromStringAndSize(NULL, 0);
@@ -481,7 +474,7 @@ iobase_readline(PyObject *self, PyObject *args)
PyObject *b;
if (has_peek) {
- PyObject *readahead = PyObject_CallMethod(self, "peek", "i", 1);
+ PyObject *readahead = _PyObject_CallMethodId(self, &PyId_peek, "i", 1);
if (readahead == NULL) {
/* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals()
when EINTR occurs so we needn't do it ourselves. */
@@ -521,7 +514,7 @@ iobase_readline(PyObject *self, PyObject *args)
Py_DECREF(readahead);
}
- b = PyObject_CallMethod(self, "read", "n", nreadahead);
+ b = _PyObject_CallMethodId(self, &PyId_read, "n", nreadahead);
if (b == NULL) {
/* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals()
when EINTR occurs so we needn't do it ourselves. */
@@ -613,7 +606,9 @@ iobase_readlines(PyObject *self, PyObject *args)
/* XXX special-casing this made sense in the Python version in order
to remove the bytecode interpretation overhead, but it could
probably be removed here. */
- PyObject *ret = PyObject_CallMethod(result, "extend", "O", self);
+ _Py_IDENTIFIER(extend);
+ PyObject *ret = _PyObject_CallMethodId(result, &PyId_extend, "O", self);
+
if (ret == NULL) {
Py_DECREF(result);
return NULL;
@@ -716,7 +711,7 @@ static PyMethodDef iobase_methods[] = {
};
static PyGetSetDef iobase_getset[] = {
- {"__dict__", (getter)iobase_get_dict, NULL, NULL},
+ {"__dict__", PyObject_GenericGetDict, NULL, NULL},
{"closed", (getter)iobase_closed_get, NULL, NULL},
{NULL}
};
@@ -793,8 +788,11 @@ rawiobase_read(PyObject *self, PyObject *args)
return NULL;
}
- if (n < 0)
- return PyObject_CallMethod(self, "readall", NULL);
+ if (n < 0) {
+ _Py_IDENTIFIER(readall);
+
+ return _PyObject_CallMethodId(self, &PyId_readall, NULL);
+ }
/* TODO: allocate a bytes object directly instead and manually construct
a writable memoryview pointing to it. */
@@ -835,8 +833,9 @@ rawiobase_readall(PyObject *self, PyObject *args)
return NULL;
while (1) {
- PyObject *data = PyObject_CallMethod(self, "read",
- "i", DEFAULT_BUFFER_SIZE);
+ _Py_IDENTIFIER(read);
+ PyObject *data = _PyObject_CallMethodId(self, &PyId_read,
+ "i", DEFAULT_BUFFER_SIZE);
if (!data) {
/* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals()
when EINTR occurs so we needn't do it ourselves. */