mirror of
https://github.com/python/cpython.git
synced 2025-11-27 13:45:25 +00:00
gh-101819: Prepare to modernize the _io extension (#104178)
* Add references to static types to _PyIO_State: * PyBufferedIOBase_Type * PyBytesIOBuffer_Type * PyIncrementalNewlineDecoder_Type * PyRawIOBase_Type * PyTextIOBase_Type * Add the defining class to methods: * _io.BytesIO.getbuffer() * _io.FileIO.close() * Add get_io_state_by_cls() function. * Add state parameter to _textiowrapper_decode() * _io_TextIOWrapper___init__() now sets self->state before calling _textiowrapper_set_decoder(). Co-authored-by: Erlend E. Aasland <erlend.aasland@protonmail.com>
This commit is contained in:
parent
8b7f37dd4c
commit
c84029179c
9 changed files with 92 additions and 37 deletions
|
|
@ -583,13 +583,18 @@ iomodule_traverse(PyObject *mod, visitproc visit, void *arg) {
|
||||||
Py_VISIT(state->locale_module);
|
Py_VISIT(state->locale_module);
|
||||||
Py_VISIT(state->unsupported_operation);
|
Py_VISIT(state->unsupported_operation);
|
||||||
|
|
||||||
|
Py_VISIT(state->PyIncrementalNewlineDecoder_Type);
|
||||||
|
Py_VISIT(state->PyRawIOBase_Type);
|
||||||
|
Py_VISIT(state->PyBufferedIOBase_Type);
|
||||||
Py_VISIT(state->PyBufferedRWPair_Type);
|
Py_VISIT(state->PyBufferedRWPair_Type);
|
||||||
Py_VISIT(state->PyBufferedRandom_Type);
|
Py_VISIT(state->PyBufferedRandom_Type);
|
||||||
Py_VISIT(state->PyBufferedReader_Type);
|
Py_VISIT(state->PyBufferedReader_Type);
|
||||||
Py_VISIT(state->PyBufferedWriter_Type);
|
Py_VISIT(state->PyBufferedWriter_Type);
|
||||||
|
Py_VISIT(state->PyBytesIOBuffer_Type);
|
||||||
Py_VISIT(state->PyBytesIO_Type);
|
Py_VISIT(state->PyBytesIO_Type);
|
||||||
Py_VISIT(state->PyFileIO_Type);
|
Py_VISIT(state->PyFileIO_Type);
|
||||||
Py_VISIT(state->PyStringIO_Type);
|
Py_VISIT(state->PyStringIO_Type);
|
||||||
|
Py_VISIT(state->PyTextIOBase_Type);
|
||||||
Py_VISIT(state->PyTextIOWrapper_Type);
|
Py_VISIT(state->PyTextIOWrapper_Type);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -604,13 +609,18 @@ iomodule_clear(PyObject *mod) {
|
||||||
Py_CLEAR(state->locale_module);
|
Py_CLEAR(state->locale_module);
|
||||||
Py_CLEAR(state->unsupported_operation);
|
Py_CLEAR(state->unsupported_operation);
|
||||||
|
|
||||||
|
Py_CLEAR(state->PyIncrementalNewlineDecoder_Type);
|
||||||
|
Py_CLEAR(state->PyRawIOBase_Type);
|
||||||
|
Py_CLEAR(state->PyBufferedIOBase_Type);
|
||||||
Py_CLEAR(state->PyBufferedRWPair_Type);
|
Py_CLEAR(state->PyBufferedRWPair_Type);
|
||||||
Py_CLEAR(state->PyBufferedRandom_Type);
|
Py_CLEAR(state->PyBufferedRandom_Type);
|
||||||
Py_CLEAR(state->PyBufferedReader_Type);
|
Py_CLEAR(state->PyBufferedReader_Type);
|
||||||
Py_CLEAR(state->PyBufferedWriter_Type);
|
Py_CLEAR(state->PyBufferedWriter_Type);
|
||||||
|
Py_CLEAR(state->PyBytesIOBuffer_Type);
|
||||||
Py_CLEAR(state->PyBytesIO_Type);
|
Py_CLEAR(state->PyBytesIO_Type);
|
||||||
Py_CLEAR(state->PyFileIO_Type);
|
Py_CLEAR(state->PyFileIO_Type);
|
||||||
Py_CLEAR(state->PyStringIO_Type);
|
Py_CLEAR(state->PyStringIO_Type);
|
||||||
|
Py_CLEAR(state->PyTextIOBase_Type);
|
||||||
Py_CLEAR(state->PyTextIOWrapper_Type);
|
Py_CLEAR(state->PyTextIOWrapper_Type);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -749,24 +759,33 @@ PyInit__io(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Base classes
|
||||||
|
state->PyIncrementalNewlineDecoder_Type = (PyTypeObject *)Py_NewRef(&PyIncrementalNewlineDecoder_Type);
|
||||||
|
|
||||||
|
// PyIOBase_Type subclasses
|
||||||
|
state->PyRawIOBase_Type = (PyTypeObject *)Py_NewRef(&PyRawIOBase_Type);
|
||||||
|
state->PyBufferedIOBase_Type = (PyTypeObject *)Py_NewRef(&PyBufferedIOBase_Type);
|
||||||
|
state->PyTextIOBase_Type = (PyTypeObject *)Py_NewRef(&PyTextIOBase_Type);
|
||||||
|
|
||||||
// PyBufferedIOBase_Type(PyIOBase_Type) subclasses
|
// PyBufferedIOBase_Type(PyIOBase_Type) subclasses
|
||||||
ADD_TYPE(m, state->PyBytesIO_Type, &bytesio_spec, &PyBufferedIOBase_Type);
|
ADD_TYPE(m, state->PyBytesIO_Type, &bytesio_spec, state->PyBufferedIOBase_Type);
|
||||||
ADD_TYPE(m, state->PyBufferedWriter_Type, &bufferedwriter_spec,
|
ADD_TYPE(m, state->PyBufferedWriter_Type, &bufferedwriter_spec,
|
||||||
&PyBufferedIOBase_Type);
|
state->PyBufferedIOBase_Type);
|
||||||
ADD_TYPE(m, state->PyBufferedReader_Type, &bufferedreader_spec,
|
ADD_TYPE(m, state->PyBufferedReader_Type, &bufferedreader_spec,
|
||||||
&PyBufferedIOBase_Type);
|
state->PyBufferedIOBase_Type);
|
||||||
ADD_TYPE(m, state->PyBufferedRWPair_Type, &bufferedrwpair_spec,
|
ADD_TYPE(m, state->PyBufferedRWPair_Type, &bufferedrwpair_spec,
|
||||||
&PyBufferedIOBase_Type);
|
state->PyBufferedIOBase_Type);
|
||||||
ADD_TYPE(m, state->PyBufferedRandom_Type, &bufferedrandom_spec,
|
ADD_TYPE(m, state->PyBufferedRandom_Type, &bufferedrandom_spec,
|
||||||
&PyBufferedIOBase_Type);
|
state->PyBufferedIOBase_Type);
|
||||||
|
|
||||||
// PyRawIOBase_Type(PyIOBase_Type) subclasses
|
// PyRawIOBase_Type(PyIOBase_Type) subclasses
|
||||||
ADD_TYPE(m, state->PyFileIO_Type, &fileio_spec, &PyRawIOBase_Type);
|
state->PyBytesIOBuffer_Type = (PyTypeObject *)Py_NewRef(&_PyBytesIOBuffer_Type);
|
||||||
|
ADD_TYPE(m, state->PyFileIO_Type, &fileio_spec, state->PyRawIOBase_Type);
|
||||||
|
|
||||||
// PyTextIOBase_Type(PyIOBase_Type) subclasses
|
// PyTextIOBase_Type(PyIOBase_Type) subclasses
|
||||||
ADD_TYPE(m, state->PyStringIO_Type, &stringio_spec, &PyTextIOBase_Type);
|
ADD_TYPE(m, state->PyStringIO_Type, &stringio_spec, state->PyTextIOBase_Type);
|
||||||
ADD_TYPE(m, state->PyTextIOWrapper_Type, &textiowrapper_spec,
|
ADD_TYPE(m, state->PyTextIOWrapper_Type, &textiowrapper_spec,
|
||||||
&PyTextIOBase_Type);
|
state->PyTextIOBase_Type);
|
||||||
|
|
||||||
state->initialized = 1;
|
state->initialized = 1;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include "exports.h"
|
#include "exports.h"
|
||||||
|
|
||||||
#include "pycore_moduleobject.h" // _PyModule_GetState()
|
#include "pycore_moduleobject.h" // _PyModule_GetState()
|
||||||
|
#include "pycore_typeobject.h" // _PyType_GetModuleState()
|
||||||
#include "structmember.h"
|
#include "structmember.h"
|
||||||
|
|
||||||
/* ABCs */
|
/* ABCs */
|
||||||
|
|
@ -147,13 +148,18 @@ typedef struct {
|
||||||
PyObject *unsupported_operation;
|
PyObject *unsupported_operation;
|
||||||
|
|
||||||
/* Types */
|
/* Types */
|
||||||
|
PyTypeObject *PyIncrementalNewlineDecoder_Type;
|
||||||
|
PyTypeObject *PyRawIOBase_Type;
|
||||||
|
PyTypeObject *PyBufferedIOBase_Type;
|
||||||
PyTypeObject *PyBufferedRWPair_Type;
|
PyTypeObject *PyBufferedRWPair_Type;
|
||||||
PyTypeObject *PyBufferedRandom_Type;
|
PyTypeObject *PyBufferedRandom_Type;
|
||||||
PyTypeObject *PyBufferedReader_Type;
|
PyTypeObject *PyBufferedReader_Type;
|
||||||
PyTypeObject *PyBufferedWriter_Type;
|
PyTypeObject *PyBufferedWriter_Type;
|
||||||
|
PyTypeObject *PyBytesIOBuffer_Type;
|
||||||
PyTypeObject *PyBytesIO_Type;
|
PyTypeObject *PyBytesIO_Type;
|
||||||
PyTypeObject *PyFileIO_Type;
|
PyTypeObject *PyFileIO_Type;
|
||||||
PyTypeObject *PyStringIO_Type;
|
PyTypeObject *PyStringIO_Type;
|
||||||
|
PyTypeObject *PyTextIOBase_Type;
|
||||||
PyTypeObject *PyTextIOWrapper_Type;
|
PyTypeObject *PyTextIOWrapper_Type;
|
||||||
} _PyIO_State;
|
} _PyIO_State;
|
||||||
|
|
||||||
|
|
@ -168,6 +174,14 @@ get_io_state(PyObject *module)
|
||||||
return (_PyIO_State *)state;
|
return (_PyIO_State *)state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline _PyIO_State *
|
||||||
|
get_io_state_by_cls(PyTypeObject *cls)
|
||||||
|
{
|
||||||
|
void *state = _PyType_GetModuleState(cls);
|
||||||
|
assert(state != NULL);
|
||||||
|
return (_PyIO_State *)state;
|
||||||
|
}
|
||||||
|
|
||||||
static inline _PyIO_State *
|
static inline _PyIO_State *
|
||||||
find_io_state_by_def(PyTypeObject *type)
|
find_io_state_by_def(PyTypeObject *type)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2231,7 +2231,7 @@ bufferedrwpair_close(rwpair *self, PyObject *Py_UNUSED(ignored))
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Py_DECREF(ret);
|
Py_DECREF(ret);
|
||||||
}
|
}
|
||||||
ret = _forward_call(self->reader, &_Py_ID(close), NULL);
|
ret = _forward_call(self->reader, &_Py_ID(close), NULL);
|
||||||
if (exc != NULL) {
|
if (exc != NULL) {
|
||||||
_PyErr_ChainExceptions1(exc);
|
_PyErr_ChainExceptions1(exc);
|
||||||
|
|
|
||||||
|
|
@ -308,14 +308,18 @@ _io_BytesIO_flush_impl(bytesio *self)
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
_io.BytesIO.getbuffer
|
_io.BytesIO.getbuffer
|
||||||
|
|
||||||
|
cls: defining_class
|
||||||
|
/
|
||||||
|
|
||||||
Get a read-write view over the contents of the BytesIO object.
|
Get a read-write view over the contents of the BytesIO object.
|
||||||
[clinic start generated code]*/
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_io_BytesIO_getbuffer_impl(bytesio *self)
|
_io_BytesIO_getbuffer_impl(bytesio *self, PyTypeObject *cls)
|
||||||
/*[clinic end generated code: output=72cd7c6e13aa09ed input=8f738ef615865176]*/
|
/*[clinic end generated code: output=045091d7ce87fe4e input=0668fbb48f95dffa]*/
|
||||||
{
|
{
|
||||||
PyTypeObject *type = &_PyBytesIOBuffer_Type;
|
_PyIO_State *state = get_io_state_by_cls(cls);
|
||||||
|
PyTypeObject *type = state->PyBytesIOBuffer_Type;
|
||||||
bytesiobuf *buf;
|
bytesiobuf *buf;
|
||||||
PyObject *view;
|
PyObject *view;
|
||||||
|
|
||||||
|
|
|
||||||
14
Modules/_io/clinic/bytesio.c.h
generated
14
Modules/_io/clinic/bytesio.c.h
generated
|
|
@ -87,15 +87,19 @@ PyDoc_STRVAR(_io_BytesIO_getbuffer__doc__,
|
||||||
"Get a read-write view over the contents of the BytesIO object.");
|
"Get a read-write view over the contents of the BytesIO object.");
|
||||||
|
|
||||||
#define _IO_BYTESIO_GETBUFFER_METHODDEF \
|
#define _IO_BYTESIO_GETBUFFER_METHODDEF \
|
||||||
{"getbuffer", (PyCFunction)_io_BytesIO_getbuffer, METH_NOARGS, _io_BytesIO_getbuffer__doc__},
|
{"getbuffer", _PyCFunction_CAST(_io_BytesIO_getbuffer), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io_BytesIO_getbuffer__doc__},
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_io_BytesIO_getbuffer_impl(bytesio *self);
|
_io_BytesIO_getbuffer_impl(bytesio *self, PyTypeObject *cls);
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_io_BytesIO_getbuffer(bytesio *self, PyObject *Py_UNUSED(ignored))
|
_io_BytesIO_getbuffer(bytesio *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
|
||||||
{
|
{
|
||||||
return _io_BytesIO_getbuffer_impl(self);
|
if (nargs) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "getbuffer() takes no arguments");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return _io_BytesIO_getbuffer_impl(self, cls);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(_io_BytesIO_getvalue__doc__,
|
PyDoc_STRVAR(_io_BytesIO_getvalue__doc__,
|
||||||
|
|
@ -534,4 +538,4 @@ skip_optional_pos:
|
||||||
exit:
|
exit:
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
/*[clinic end generated code: output=a44770efbaeb80dd input=a9049054013a1b77]*/
|
/*[clinic end generated code: output=098584d485420b65 input=a9049054013a1b77]*/
|
||||||
|
|
|
||||||
14
Modules/_io/clinic/fileio.c.h
generated
14
Modules/_io/clinic/fileio.c.h
generated
|
|
@ -18,15 +18,19 @@ PyDoc_STRVAR(_io_FileIO_close__doc__,
|
||||||
"called more than once without error.");
|
"called more than once without error.");
|
||||||
|
|
||||||
#define _IO_FILEIO_CLOSE_METHODDEF \
|
#define _IO_FILEIO_CLOSE_METHODDEF \
|
||||||
{"close", (PyCFunction)_io_FileIO_close, METH_NOARGS, _io_FileIO_close__doc__},
|
{"close", _PyCFunction_CAST(_io_FileIO_close), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io_FileIO_close__doc__},
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_io_FileIO_close_impl(fileio *self);
|
_io_FileIO_close_impl(fileio *self, PyTypeObject *cls);
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_io_FileIO_close(fileio *self, PyObject *Py_UNUSED(ignored))
|
_io_FileIO_close(fileio *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
|
||||||
{
|
{
|
||||||
return _io_FileIO_close_impl(self);
|
if (nargs) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "close() takes no arguments");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return _io_FileIO_close_impl(self, cls);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(_io_FileIO___init____doc__,
|
PyDoc_STRVAR(_io_FileIO___init____doc__,
|
||||||
|
|
@ -466,4 +470,4 @@ _io_FileIO_isatty(fileio *self, PyObject *Py_UNUSED(ignored))
|
||||||
#ifndef _IO_FILEIO_TRUNCATE_METHODDEF
|
#ifndef _IO_FILEIO_TRUNCATE_METHODDEF
|
||||||
#define _IO_FILEIO_TRUNCATE_METHODDEF
|
#define _IO_FILEIO_TRUNCATE_METHODDEF
|
||||||
#endif /* !defined(_IO_FILEIO_TRUNCATE_METHODDEF) */
|
#endif /* !defined(_IO_FILEIO_TRUNCATE_METHODDEF) */
|
||||||
/*[clinic end generated code: output=27f883807a6c29ae input=a9049054013a1b77]*/
|
/*[clinic end generated code: output=29ed2ae6c451c139 input=a9049054013a1b77]*/
|
||||||
|
|
|
||||||
|
|
@ -130,6 +130,9 @@ internal_close(fileio *self)
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
_io.FileIO.close
|
_io.FileIO.close
|
||||||
|
|
||||||
|
cls: defining_class
|
||||||
|
/
|
||||||
|
|
||||||
Close the file.
|
Close the file.
|
||||||
|
|
||||||
A closed file cannot be used for further I/O operations. close() may be
|
A closed file cannot be used for further I/O operations. close() may be
|
||||||
|
|
@ -137,18 +140,20 @@ called more than once without error.
|
||||||
[clinic start generated code]*/
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_io_FileIO_close_impl(fileio *self)
|
_io_FileIO_close_impl(fileio *self, PyTypeObject *cls)
|
||||||
/*[clinic end generated code: output=7737a319ef3bad0b input=f35231760d54a522]*/
|
/*[clinic end generated code: output=c30cbe9d1f23ca58 input=70da49e63db7c64d]*/
|
||||||
{
|
{
|
||||||
PyObject *res;
|
PyObject *res;
|
||||||
PyObject *exc;
|
|
||||||
int rc;
|
int rc;
|
||||||
res = PyObject_CallMethodOneArg((PyObject*)&PyRawIOBase_Type,
|
_PyIO_State *state = get_io_state_by_cls(cls);
|
||||||
|
res = PyObject_CallMethodOneArg((PyObject*)state->PyRawIOBase_Type,
|
||||||
&_Py_ID(close), (PyObject *)self);
|
&_Py_ID(close), (PyObject *)self);
|
||||||
if (!self->closefd) {
|
if (!self->closefd) {
|
||||||
self->fd = -1;
|
self->fd = -1;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyObject *exc;
|
||||||
if (res == NULL) {
|
if (res == NULL) {
|
||||||
exc = PyErr_GetRaisedException();
|
exc = PyErr_GetRaisedException();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -716,9 +716,10 @@ _io_StringIO___init___impl(stringio *self, PyObject *value,
|
||||||
self->writenl = Py_NewRef(self->readnl);
|
self->writenl = Py_NewRef(self->readnl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_PyIO_State *module_state = find_io_state_by_def(Py_TYPE(self));
|
||||||
if (self->readuniversal) {
|
if (self->readuniversal) {
|
||||||
self->decoder = PyObject_CallFunctionObjArgs(
|
self->decoder = PyObject_CallFunctionObjArgs(
|
||||||
(PyObject *)&PyIncrementalNewlineDecoder_Type,
|
(PyObject *)module_state->PyIncrementalNewlineDecoder_Type,
|
||||||
Py_None, self->readtranslate ? Py_True : Py_False, NULL);
|
Py_None, self->readtranslate ? Py_True : Py_False, NULL);
|
||||||
if (self->decoder == NULL)
|
if (self->decoder == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -750,7 +751,7 @@ _io_StringIO___init___impl(stringio *self, PyObject *value,
|
||||||
self->state = STATE_ACCUMULATING;
|
self->state = STATE_ACCUMULATING;
|
||||||
}
|
}
|
||||||
self->pos = 0;
|
self->pos = 0;
|
||||||
self->module_state = find_io_state_by_def(Py_TYPE(self));
|
self->module_state = module_state;
|
||||||
self->closed = 0;
|
self->closed = 0;
|
||||||
self->ok = 1;
|
self->ok = 1;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -18,10 +18,10 @@
|
||||||
|
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
module _io
|
module _io
|
||||||
class _io.IncrementalNewlineDecoder "nldecoder_object *" "&PyIncrementalNewlineDecoder_Type"
|
class _io.IncrementalNewlineDecoder "nldecoder_object *" "clinic_state()->PyIncrementalNewlineDecoder_Type"
|
||||||
class _io.TextIOWrapper "textio *" "clinic_state()->TextIOWrapper_Type"
|
class _io.TextIOWrapper "textio *" "clinic_state()->TextIOWrapper_Type"
|
||||||
[clinic start generated code]*/
|
[clinic start generated code]*/
|
||||||
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=d3f032e90f74c8f2]*/
|
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=81f67cf54eaa6001]*/
|
||||||
|
|
||||||
/* TextIOBase */
|
/* TextIOBase */
|
||||||
|
|
||||||
|
|
@ -872,8 +872,9 @@ _textiowrapper_set_decoder(textio *self, PyObject *codec_info,
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (self->readuniversal) {
|
if (self->readuniversal) {
|
||||||
|
_PyIO_State *state = self->state;
|
||||||
PyObject *incrementalDecoder = PyObject_CallFunctionObjArgs(
|
PyObject *incrementalDecoder = PyObject_CallFunctionObjArgs(
|
||||||
(PyObject *)&PyIncrementalNewlineDecoder_Type,
|
(PyObject *)state->PyIncrementalNewlineDecoder_Type,
|
||||||
self->decoder, self->readtranslate ? Py_True : Py_False, NULL);
|
self->decoder, self->readtranslate ? Py_True : Py_False, NULL);
|
||||||
if (incrementalDecoder == NULL)
|
if (incrementalDecoder == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -884,11 +885,12 @@ _textiowrapper_set_decoder(textio *self, PyObject *codec_info,
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
_textiowrapper_decode(PyObject *decoder, PyObject *bytes, int eof)
|
_textiowrapper_decode(_PyIO_State *state, PyObject *decoder, PyObject *bytes,
|
||||||
|
int eof)
|
||||||
{
|
{
|
||||||
PyObject *chars;
|
PyObject *chars;
|
||||||
|
|
||||||
if (Py_IS_TYPE(decoder, &PyIncrementalNewlineDecoder_Type))
|
if (Py_IS_TYPE(decoder, state->PyIncrementalNewlineDecoder_Type))
|
||||||
chars = _PyIncrementalNewlineDecoder_decode(decoder, bytes, eof);
|
chars = _PyIncrementalNewlineDecoder_decode(decoder, bytes, eof);
|
||||||
else
|
else
|
||||||
chars = PyObject_CallMethodObjArgs(decoder, &_Py_ID(decode), bytes,
|
chars = PyObject_CallMethodObjArgs(decoder, &_Py_ID(decode), bytes,
|
||||||
|
|
@ -1167,6 +1169,8 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer,
|
||||||
self->buffer = Py_NewRef(buffer);
|
self->buffer = Py_NewRef(buffer);
|
||||||
|
|
||||||
/* Build the decoder object */
|
/* Build the decoder object */
|
||||||
|
_PyIO_State *state = find_io_state_by_def(Py_TYPE(self));
|
||||||
|
self->state = state;
|
||||||
if (_textiowrapper_set_decoder(self, codec_info, PyUnicode_AsUTF8(errors)) != 0)
|
if (_textiowrapper_set_decoder(self, codec_info, PyUnicode_AsUTF8(errors)) != 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
|
@ -1177,7 +1181,6 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer,
|
||||||
/* Finished sorting out the codec details */
|
/* Finished sorting out the codec details */
|
||||||
Py_CLEAR(codec_info);
|
Py_CLEAR(codec_info);
|
||||||
|
|
||||||
_PyIO_State *state = find_io_state_by_def(Py_TYPE(self));
|
|
||||||
if (Py_IS_TYPE(buffer, state->PyBufferedReader_Type) ||
|
if (Py_IS_TYPE(buffer, state->PyBufferedReader_Type) ||
|
||||||
Py_IS_TYPE(buffer, state->PyBufferedWriter_Type) ||
|
Py_IS_TYPE(buffer, state->PyBufferedWriter_Type) ||
|
||||||
Py_IS_TYPE(buffer, state->PyBufferedRandom_Type))
|
Py_IS_TYPE(buffer, state->PyBufferedRandom_Type))
|
||||||
|
|
@ -1214,7 +1217,6 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer,
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
self->state = state;
|
|
||||||
self->ok = 1;
|
self->ok = 1;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
@ -1843,7 +1845,8 @@ textiowrapper_read_chunk(textio *self, Py_ssize_t size_hint)
|
||||||
nbytes = input_chunk_buf.len;
|
nbytes = input_chunk_buf.len;
|
||||||
eof = (nbytes == 0);
|
eof = (nbytes == 0);
|
||||||
|
|
||||||
decoded_chars = _textiowrapper_decode(self->decoder, input_chunk, eof);
|
decoded_chars = _textiowrapper_decode(self->state, self->decoder,
|
||||||
|
input_chunk, eof);
|
||||||
PyBuffer_Release(&input_chunk_buf);
|
PyBuffer_Release(&input_chunk_buf);
|
||||||
if (decoded_chars == NULL)
|
if (decoded_chars == NULL)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -1913,7 +1916,8 @@ _io_TextIOWrapper_read_impl(textio *self, Py_ssize_t n)
|
||||||
if (bytes == NULL)
|
if (bytes == NULL)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (Py_IS_TYPE(self->decoder, &PyIncrementalNewlineDecoder_Type))
|
_PyIO_State *state = self->state;
|
||||||
|
if (Py_IS_TYPE(self->decoder, state->PyIncrementalNewlineDecoder_Type))
|
||||||
decoded = _PyIncrementalNewlineDecoder_decode(self->decoder,
|
decoded = _PyIncrementalNewlineDecoder_decode(self->decoder,
|
||||||
bytes, 1);
|
bytes, 1);
|
||||||
else
|
else
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue