mirror of
https://github.com/python/cpython.git
synced 2025-08-03 08:34:29 +00:00
allow more operations to work on detached streams (closes #23093)
Patch by Martin Panter.
This commit is contained in:
parent
fe3dc376fa
commit
10e76b67c9
5 changed files with 61 additions and 42 deletions
|
@ -1359,7 +1359,7 @@ buffered_repr(buffered *self)
|
|||
|
||||
nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
|
||||
if (nameobj == NULL) {
|
||||
if (PyErr_ExceptionMatches(PyExc_AttributeError))
|
||||
if (PyErr_ExceptionMatches(PyExc_Exception))
|
||||
PyErr_Clear();
|
||||
else
|
||||
return NULL;
|
||||
|
|
|
@ -1219,25 +1219,27 @@ textiowrapper_closed_get(textio *self, void *context);
|
|||
|
||||
#define CHECK_INITIALIZED(self) \
|
||||
if (self->ok <= 0) { \
|
||||
if (self->detached) { \
|
||||
PyErr_SetString(PyExc_ValueError, \
|
||||
"underlying buffer has been detached"); \
|
||||
} else { \
|
||||
PyErr_SetString(PyExc_ValueError, \
|
||||
"I/O operation on uninitialized object"); \
|
||||
} \
|
||||
PyErr_SetString(PyExc_ValueError, \
|
||||
"I/O operation on uninitialized object"); \
|
||||
return NULL; \
|
||||
}
|
||||
|
||||
#define CHECK_INITIALIZED_INT(self) \
|
||||
#define CHECK_ATTACHED(self) \
|
||||
CHECK_INITIALIZED(self); \
|
||||
if (self->detached) { \
|
||||
PyErr_SetString(PyExc_ValueError, \
|
||||
"underlying buffer has been detached"); \
|
||||
return NULL; \
|
||||
}
|
||||
|
||||
#define CHECK_ATTACHED_INT(self) \
|
||||
if (self->ok <= 0) { \
|
||||
if (self->detached) { \
|
||||
PyErr_SetString(PyExc_ValueError, \
|
||||
"underlying buffer has been detached"); \
|
||||
} else { \
|
||||
PyErr_SetString(PyExc_ValueError, \
|
||||
"I/O operation on uninitialized object"); \
|
||||
} \
|
||||
PyErr_SetString(PyExc_ValueError, \
|
||||
"I/O operation on uninitialized object"); \
|
||||
return -1; \
|
||||
} else if (self->detached) { \
|
||||
PyErr_SetString(PyExc_ValueError, \
|
||||
"underlying buffer has been detached"); \
|
||||
return -1; \
|
||||
}
|
||||
|
||||
|
@ -1246,7 +1248,7 @@ static PyObject *
|
|||
textiowrapper_detach(textio *self)
|
||||
{
|
||||
PyObject *buffer, *res;
|
||||
CHECK_INITIALIZED(self);
|
||||
CHECK_ATTACHED(self);
|
||||
res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
|
||||
if (res == NULL)
|
||||
return NULL;
|
||||
|
@ -1254,7 +1256,6 @@ textiowrapper_detach(textio *self)
|
|||
buffer = self->buffer;
|
||||
self->buffer = NULL;
|
||||
self->detached = 1;
|
||||
self->ok = 0;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
@ -1299,7 +1300,7 @@ textiowrapper_write(textio *self, PyObject *args)
|
|||
int haslf = 0;
|
||||
int needflush = 0, text_needflush = 0;
|
||||
|
||||
CHECK_INITIALIZED(self);
|
||||
CHECK_ATTACHED(self);
|
||||
|
||||
if (!PyArg_ParseTuple(args, "U:write", &text)) {
|
||||
return NULL;
|
||||
|
@ -1556,7 +1557,7 @@ textiowrapper_read(textio *self, PyObject *args)
|
|||
Py_ssize_t n = -1;
|
||||
PyObject *result = NULL, *chunks = NULL;
|
||||
|
||||
CHECK_INITIALIZED(self);
|
||||
CHECK_ATTACHED(self);
|
||||
|
||||
if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n))
|
||||
return NULL;
|
||||
|
@ -1931,7 +1932,7 @@ textiowrapper_readline(textio *self, PyObject *args)
|
|||
{
|
||||
Py_ssize_t limit = -1;
|
||||
|
||||
CHECK_INITIALIZED(self);
|
||||
CHECK_ATTACHED(self);
|
||||
if (!PyArg_ParseTuple(args, "|n:readline", &limit)) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -2069,7 +2070,7 @@ textiowrapper_seek(textio *self, PyObject *args)
|
|||
PyObject *res;
|
||||
int cmp;
|
||||
|
||||
CHECK_INITIALIZED(self);
|
||||
CHECK_ATTACHED(self);
|
||||
|
||||
if (!PyArg_ParseTuple(args, "O|i:seek", &cookieObj, &whence))
|
||||
return NULL;
|
||||
|
@ -2249,7 +2250,7 @@ textiowrapper_tell(textio *self, PyObject *args)
|
|||
Py_ssize_t dec_buffer_len;
|
||||
int dec_flags;
|
||||
|
||||
CHECK_INITIALIZED(self);
|
||||
CHECK_ATTACHED(self);
|
||||
CHECK_CLOSED(self);
|
||||
|
||||
if (!self->seekable) {
|
||||
|
@ -2452,7 +2453,7 @@ textiowrapper_truncate(textio *self, PyObject *args)
|
|||
PyObject *pos = Py_None;
|
||||
PyObject *res;
|
||||
|
||||
CHECK_INITIALIZED(self)
|
||||
CHECK_ATTACHED(self)
|
||||
if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -2475,9 +2476,10 @@ textiowrapper_repr(textio *self)
|
|||
res = PyUnicode_FromString("<_io.TextIOWrapper");
|
||||
if (res == NULL)
|
||||
return NULL;
|
||||
|
||||
nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
|
||||
if (nameobj == NULL) {
|
||||
if (PyErr_ExceptionMatches(PyExc_AttributeError))
|
||||
if (PyErr_ExceptionMatches(PyExc_Exception))
|
||||
PyErr_Clear();
|
||||
else
|
||||
goto error;
|
||||
|
@ -2493,7 +2495,7 @@ textiowrapper_repr(textio *self)
|
|||
}
|
||||
modeobj = _PyObject_GetAttrId((PyObject *) self, &PyId_mode);
|
||||
if (modeobj == NULL) {
|
||||
if (PyErr_ExceptionMatches(PyExc_AttributeError))
|
||||
if (PyErr_ExceptionMatches(PyExc_Exception))
|
||||
PyErr_Clear();
|
||||
else
|
||||
goto error;
|
||||
|
@ -2522,35 +2524,35 @@ error:
|
|||
static PyObject *
|
||||
textiowrapper_fileno(textio *self, PyObject *args)
|
||||
{
|
||||
CHECK_INITIALIZED(self);
|
||||
CHECK_ATTACHED(self);
|
||||
return _PyObject_CallMethodId(self->buffer, &PyId_fileno, NULL);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
textiowrapper_seekable(textio *self, PyObject *args)
|
||||
{
|
||||
CHECK_INITIALIZED(self);
|
||||
CHECK_ATTACHED(self);
|
||||
return _PyObject_CallMethodId(self->buffer, &PyId_seekable, NULL);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
textiowrapper_readable(textio *self, PyObject *args)
|
||||
{
|
||||
CHECK_INITIALIZED(self);
|
||||
CHECK_ATTACHED(self);
|
||||
return _PyObject_CallMethodId(self->buffer, &PyId_readable, NULL);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
textiowrapper_writable(textio *self, PyObject *args)
|
||||
{
|
||||
CHECK_INITIALIZED(self);
|
||||
CHECK_ATTACHED(self);
|
||||
return _PyObject_CallMethodId(self->buffer, &PyId_writable, NULL);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
textiowrapper_isatty(textio *self, PyObject *args)
|
||||
{
|
||||
CHECK_INITIALIZED(self);
|
||||
CHECK_ATTACHED(self);
|
||||
return _PyObject_CallMethodId(self->buffer, &PyId_isatty, NULL);
|
||||
}
|
||||
|
||||
|
@ -2565,7 +2567,7 @@ textiowrapper_getstate(textio *self, PyObject *args)
|
|||
static PyObject *
|
||||
textiowrapper_flush(textio *self, PyObject *args)
|
||||
{
|
||||
CHECK_INITIALIZED(self);
|
||||
CHECK_ATTACHED(self);
|
||||
CHECK_CLOSED(self);
|
||||
self->telling = self->seekable;
|
||||
if (_textiowrapper_writeflush(self) < 0)
|
||||
|
@ -2578,7 +2580,7 @@ textiowrapper_close(textio *self, PyObject *args)
|
|||
{
|
||||
PyObject *res;
|
||||
int r;
|
||||
CHECK_INITIALIZED(self);
|
||||
CHECK_ATTACHED(self);
|
||||
|
||||
res = textiowrapper_closed_get(self, NULL);
|
||||
if (res == NULL)
|
||||
|
@ -2620,7 +2622,7 @@ textiowrapper_iternext(textio *self)
|
|||
{
|
||||
PyObject *line;
|
||||
|
||||
CHECK_INITIALIZED(self);
|
||||
CHECK_ATTACHED(self);
|
||||
|
||||
self->telling = 0;
|
||||
if (Py_TYPE(self) == &PyTextIOWrapper_Type) {
|
||||
|
@ -2656,14 +2658,14 @@ textiowrapper_iternext(textio *self)
|
|||
static PyObject *
|
||||
textiowrapper_name_get(textio *self, void *context)
|
||||
{
|
||||
CHECK_INITIALIZED(self);
|
||||
CHECK_ATTACHED(self);
|
||||
return _PyObject_GetAttrId(self->buffer, &PyId_name);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
textiowrapper_closed_get(textio *self, void *context)
|
||||
{
|
||||
CHECK_INITIALIZED(self);
|
||||
CHECK_ATTACHED(self);
|
||||
return PyObject_GetAttr(self->buffer, _PyIO_str_closed);
|
||||
}
|
||||
|
||||
|
@ -2671,7 +2673,7 @@ static PyObject *
|
|||
textiowrapper_newlines_get(textio *self, void *context)
|
||||
{
|
||||
PyObject *res;
|
||||
CHECK_INITIALIZED(self);
|
||||
CHECK_ATTACHED(self);
|
||||
if (self->decoder == NULL)
|
||||
Py_RETURN_NONE;
|
||||
res = PyObject_GetAttr(self->decoder, _PyIO_str_newlines);
|
||||
|
@ -2697,7 +2699,7 @@ textiowrapper_errors_get(textio *self, void *context)
|
|||
static PyObject *
|
||||
textiowrapper_chunk_size_get(textio *self, void *context)
|
||||
{
|
||||
CHECK_INITIALIZED(self);
|
||||
CHECK_ATTACHED(self);
|
||||
return PyLong_FromSsize_t(self->chunk_size);
|
||||
}
|
||||
|
||||
|
@ -2705,7 +2707,7 @@ static int
|
|||
textiowrapper_chunk_size_set(textio *self, PyObject *arg, void *context)
|
||||
{
|
||||
Py_ssize_t n;
|
||||
CHECK_INITIALIZED_INT(self);
|
||||
CHECK_ATTACHED_INT(self);
|
||||
n = PyNumber_AsSsize_t(arg, PyExc_ValueError);
|
||||
if (n == -1 && PyErr_Occurred())
|
||||
return -1;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue