Py_VISIT(state->locale_module);
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->PyBufferedRandom_Type);
Py_VISIT(state->PyBufferedReader_Type);
Py_VISIT(state->PyBufferedWriter_Type);
+ Py_VISIT(state->PyBytesIOBuffer_Type);
Py_VISIT(state->PyBytesIO_Type);
Py_VISIT(state->PyFileIO_Type);
Py_VISIT(state->PyStringIO_Type);
+ Py_VISIT(state->PyTextIOBase_Type);
Py_VISIT(state->PyTextIOWrapper_Type);
return 0;
}
Py_CLEAR(state->locale_module);
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->PyBufferedRandom_Type);
Py_CLEAR(state->PyBufferedReader_Type);
Py_CLEAR(state->PyBufferedWriter_Type);
+ Py_CLEAR(state->PyBytesIOBuffer_Type);
Py_CLEAR(state->PyBytesIO_Type);
Py_CLEAR(state->PyFileIO_Type);
Py_CLEAR(state->PyStringIO_Type);
+ Py_CLEAR(state->PyTextIOBase_Type);
Py_CLEAR(state->PyTextIOWrapper_Type);
return 0;
}
}
}
+ // 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
- 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,
- &PyBufferedIOBase_Type);
+ state->PyBufferedIOBase_Type);
ADD_TYPE(m, state->PyBufferedReader_Type, &bufferedreader_spec,
- &PyBufferedIOBase_Type);
+ state->PyBufferedIOBase_Type);
ADD_TYPE(m, state->PyBufferedRWPair_Type, &bufferedrwpair_spec,
- &PyBufferedIOBase_Type);
+ state->PyBufferedIOBase_Type);
ADD_TYPE(m, state->PyBufferedRandom_Type, &bufferedrandom_spec,
- &PyBufferedIOBase_Type);
+ state->PyBufferedIOBase_Type);
// 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
- 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,
- &PyTextIOBase_Type);
+ state->PyTextIOBase_Type);
state->initialized = 1;
#include "exports.h"
#include "pycore_moduleobject.h" // _PyModule_GetState()
+#include "pycore_typeobject.h" // _PyType_GetModuleState()
#include "structmember.h"
/* ABCs */
PyObject *unsupported_operation;
/* Types */
+ PyTypeObject *PyIncrementalNewlineDecoder_Type;
+ PyTypeObject *PyRawIOBase_Type;
+ PyTypeObject *PyBufferedIOBase_Type;
PyTypeObject *PyBufferedRWPair_Type;
PyTypeObject *PyBufferedRandom_Type;
PyTypeObject *PyBufferedReader_Type;
PyTypeObject *PyBufferedWriter_Type;
+ PyTypeObject *PyBytesIOBuffer_Type;
PyTypeObject *PyBytesIO_Type;
PyTypeObject *PyFileIO_Type;
PyTypeObject *PyStringIO_Type;
+ PyTypeObject *PyTextIOBase_Type;
PyTypeObject *PyTextIOWrapper_Type;
} _PyIO_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 *
find_io_state_by_def(PyTypeObject *type)
{
}
else {
Py_DECREF(ret);
- }
+ }
ret = _forward_call(self->reader, &_Py_ID(close), NULL);
if (exc != NULL) {
_PyErr_ChainExceptions1(exc);
/*[clinic input]
_io.BytesIO.getbuffer
+ cls: defining_class
+ /
+
Get a read-write view over the contents of the BytesIO object.
[clinic start generated code]*/
static PyObject *
-_io_BytesIO_getbuffer_impl(bytesio *self)
-/*[clinic end generated code: output=72cd7c6e13aa09ed input=8f738ef615865176]*/
+_io_BytesIO_getbuffer_impl(bytesio *self, PyTypeObject *cls)
+/*[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;
PyObject *view;
"Get a read-write view over the contents of the BytesIO object.");
#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 *
-_io_BytesIO_getbuffer_impl(bytesio *self);
+_io_BytesIO_getbuffer_impl(bytesio *self, PyTypeObject *cls);
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__,
exit:
return return_value;
}
-/*[clinic end generated code: output=a44770efbaeb80dd input=a9049054013a1b77]*/
+/*[clinic end generated code: output=098584d485420b65 input=a9049054013a1b77]*/
"called more than once without error.");
#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 *
-_io_FileIO_close_impl(fileio *self);
+_io_FileIO_close_impl(fileio *self, PyTypeObject *cls);
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__,
#ifndef _IO_FILEIO_TRUNCATE_METHODDEF
#define _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]*/
/*[clinic input]
_io.FileIO.close
+ cls: defining_class
+ /
+
Close the file.
A closed file cannot be used for further I/O operations. close() may be
[clinic start generated code]*/
static PyObject *
-_io_FileIO_close_impl(fileio *self)
-/*[clinic end generated code: output=7737a319ef3bad0b input=f35231760d54a522]*/
+_io_FileIO_close_impl(fileio *self, PyTypeObject *cls)
+/*[clinic end generated code: output=c30cbe9d1f23ca58 input=70da49e63db7c64d]*/
{
PyObject *res;
- PyObject *exc;
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);
if (!self->closefd) {
self->fd = -1;
return res;
}
+
+ PyObject *exc;
if (res == NULL) {
exc = PyErr_GetRaisedException();
}
self->writenl = Py_NewRef(self->readnl);
}
+ _PyIO_State *module_state = find_io_state_by_def(Py_TYPE(self));
if (self->readuniversal) {
self->decoder = PyObject_CallFunctionObjArgs(
- (PyObject *)&PyIncrementalNewlineDecoder_Type,
+ (PyObject *)module_state->PyIncrementalNewlineDecoder_Type,
Py_None, self->readtranslate ? Py_True : Py_False, NULL);
if (self->decoder == NULL)
return -1;
self->state = STATE_ACCUMULATING;
}
self->pos = 0;
- self->module_state = find_io_state_by_def(Py_TYPE(self));
+ self->module_state = module_state;
self->closed = 0;
self->ok = 1;
return 0;
/*[clinic input]
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"
[clinic start generated code]*/
-/*[clinic end generated code: output=da39a3ee5e6b4b0d input=d3f032e90f74c8f2]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=81f67cf54eaa6001]*/
/* TextIOBase */
return -1;
if (self->readuniversal) {
+ _PyIO_State *state = self->state;
PyObject *incrementalDecoder = PyObject_CallFunctionObjArgs(
- (PyObject *)&PyIncrementalNewlineDecoder_Type,
+ (PyObject *)state->PyIncrementalNewlineDecoder_Type,
self->decoder, self->readtranslate ? Py_True : Py_False, NULL);
if (incrementalDecoder == NULL)
return -1;
}
static PyObject*
-_textiowrapper_decode(PyObject *decoder, PyObject *bytes, int eof)
+_textiowrapper_decode(_PyIO_State *state, PyObject *decoder, PyObject *bytes,
+ int eof)
{
PyObject *chars;
- if (Py_IS_TYPE(decoder, &PyIncrementalNewlineDecoder_Type))
+ if (Py_IS_TYPE(decoder, state->PyIncrementalNewlineDecoder_Type))
chars = _PyIncrementalNewlineDecoder_decode(decoder, bytes, eof);
else
chars = PyObject_CallMethodObjArgs(decoder, &_Py_ID(decode), bytes,
self->buffer = Py_NewRef(buffer);
/* 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)
goto error;
/* Finished sorting out the codec details */
Py_CLEAR(codec_info);
- _PyIO_State *state = find_io_state_by_def(Py_TYPE(self));
if (Py_IS_TYPE(buffer, state->PyBufferedReader_Type) ||
Py_IS_TYPE(buffer, state->PyBufferedWriter_Type) ||
Py_IS_TYPE(buffer, state->PyBufferedRandom_Type))
goto error;
}
- self->state = state;
self->ok = 1;
return 0;
nbytes = input_chunk_buf.len;
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);
if (decoded_chars == NULL)
goto fail;
if (bytes == NULL)
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,
bytes, 1);
else