mirror of
https://github.com/python/cpython.git
synced 2025-12-04 00:30:19 +00:00
implement a detach() method for BufferedIOBase and TextIOBase #5883
This commit is contained in:
parent
155374d95d
commit
d2e0c7955f
7 changed files with 214 additions and 15 deletions
|
|
@ -28,6 +28,19 @@ _unsupported(const char *message)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(TextIOBase_detach_doc,
|
||||
"Separate the underlying buffer from the TextIOBase and return it.\n"
|
||||
"\n"
|
||||
"After the underlying buffer has been detached, the TextIO is in an\n"
|
||||
"unusable state.\n"
|
||||
);
|
||||
|
||||
static PyObject *
|
||||
TextIOBase_detach(PyObject *self)
|
||||
{
|
||||
return _unsupported("detach");
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(TextIOBase_read_doc,
|
||||
"Read at most n characters from stream.\n"
|
||||
"\n"
|
||||
|
|
@ -93,6 +106,7 @@ TextIOBase_newlines_get(PyObject *self, void *context)
|
|||
|
||||
|
||||
static PyMethodDef TextIOBase_methods[] = {
|
||||
{"detach", (PyCFunction)TextIOBase_detach, METH_NOARGS, TextIOBase_detach_doc},
|
||||
{"read", TextIOBase_read, METH_VARARGS, TextIOBase_read_doc},
|
||||
{"readline", TextIOBase_readline, METH_VARARGS, TextIOBase_readline_doc},
|
||||
{"write", TextIOBase_write, METH_VARARGS, TextIOBase_write_doc},
|
||||
|
|
@ -616,6 +630,7 @@ typedef struct
|
|||
{
|
||||
PyObject_HEAD
|
||||
int ok; /* initialized? */
|
||||
int detached;
|
||||
Py_ssize_t chunk_size;
|
||||
PyObject *buffer;
|
||||
PyObject *encoding;
|
||||
|
|
@ -759,6 +774,7 @@ TextIOWrapper_init(PyTextIOWrapperObject *self, PyObject *args, PyObject *kwds)
|
|||
int r;
|
||||
|
||||
self->ok = 0;
|
||||
self->detached = 0;
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|zzzi:fileio",
|
||||
kwlist, &buffer, &encoding, &errors,
|
||||
&newline, &line_buffering))
|
||||
|
|
@ -1059,19 +1075,45 @@ TextIOWrapper_closed_get(PyTextIOWrapperObject *self, void *context);
|
|||
|
||||
#define CHECK_INITIALIZED(self) \
|
||||
if (self->ok <= 0) { \
|
||||
PyErr_SetString(PyExc_ValueError, \
|
||||
"I/O operation on uninitialized object"); \
|
||||
if (self->detached) { \
|
||||
PyErr_SetString(PyExc_ValueError, \
|
||||
"underlying buffer has been detached"); \
|
||||
} else { \
|
||||
PyErr_SetString(PyExc_ValueError, \
|
||||
"I/O operation on uninitialized object"); \
|
||||
} \
|
||||
return NULL; \
|
||||
}
|
||||
|
||||
#define CHECK_INITIALIZED_INT(self) \
|
||||
if (self->ok <= 0) { \
|
||||
PyErr_SetString(PyExc_ValueError, \
|
||||
"I/O operation on uninitialized object"); \
|
||||
if (self->detached) { \
|
||||
PyErr_SetString(PyExc_ValueError, \
|
||||
"underlying buffer has been detached"); \
|
||||
} else { \
|
||||
PyErr_SetString(PyExc_ValueError, \
|
||||
"I/O operation on uninitialized object"); \
|
||||
} \
|
||||
return -1; \
|
||||
}
|
||||
|
||||
|
||||
static PyObject *
|
||||
TextIOWrapper_detach(PyTextIOWrapperObject *self)
|
||||
{
|
||||
PyObject *buffer, *res;
|
||||
CHECK_INITIALIZED(self);
|
||||
res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
|
||||
if (res == NULL)
|
||||
return NULL;
|
||||
Py_DECREF(res);
|
||||
buffer = self->buffer;
|
||||
self->buffer = NULL;
|
||||
self->detached = 1;
|
||||
self->ok = 0;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
Py_LOCAL_INLINE(const Py_UNICODE *)
|
||||
findchar(const Py_UNICODE *s, Py_ssize_t size, Py_UNICODE ch)
|
||||
{
|
||||
|
|
@ -2341,6 +2383,7 @@ TextIOWrapper_chunk_size_set(PyTextIOWrapperObject *self,
|
|||
}
|
||||
|
||||
static PyMethodDef TextIOWrapper_methods[] = {
|
||||
{"detach", (PyCFunction)TextIOWrapper_detach, METH_NOARGS},
|
||||
{"write", (PyCFunction)TextIOWrapper_write, METH_VARARGS},
|
||||
{"read", (PyCFunction)TextIOWrapper_read, METH_VARARGS},
|
||||
{"readline", (PyCFunction)TextIOWrapper_readline, METH_VARARGS},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue