Adapt StringIO, TextIOWrapper, FileIO, Buffered*, and BytesIO types.
Automerge-Triggered-By: GH:erlend-aasland
support.gc_collect()
self.assertIsNone(wr(), wr)
+@support.cpython_only
+class TestIOCTypes(unittest.TestCase):
+ def setUp(self):
+ _io = import_helper.import_module("_io")
+ self.types = [
+ _io.BufferedRWPair,
+ _io.BufferedRandom,
+ _io.BufferedReader,
+ _io.BufferedWriter,
+ _io.BytesIO,
+ _io.FileIO,
+ _io.IncrementalNewlineDecoder,
+ _io.StringIO,
+ _io.TextIOWrapper,
+ _io._BufferedIOBase,
+ _io._BytesIOBuffer,
+ _io._IOBase,
+ _io._RawIOBase,
+ _io._TextIOBase,
+ ]
+ if sys.platform == "win32":
+ self.types.append(_io._WindowsConsoleIO)
+ self._io = _io
+
+ def test_immutable_types(self):
+ for tp in self.types:
+ with self.subTest(tp=tp):
+ with self.assertRaisesRegex(TypeError, "immutable"):
+ tp.foo = "bar"
+
+ def test_class_hierarchy(self):
+ def check_subs(types, base):
+ for tp in types:
+ with self.subTest(tp=tp, base=base):
+ self.assertTrue(issubclass(tp, base))
+
+ def recursive_check(d):
+ for k, v in d.items():
+ if isinstance(v, dict):
+ recursive_check(v)
+ elif isinstance(v, set):
+ check_subs(v, k)
+ else:
+ self.fail("corrupt test dataset")
+
+ _io = self._io
+ hierarchy = {
+ _io._IOBase: {
+ _io._BufferedIOBase: {
+ _io.BufferedRWPair,
+ _io.BufferedRandom,
+ _io.BufferedReader,
+ _io.BufferedWriter,
+ _io.BytesIO,
+ },
+ _io._RawIOBase: {
+ _io.FileIO,
+ },
+ _io._TextIOBase: {
+ _io.StringIO,
+ _io.TextIOWrapper,
+ },
+ },
+ }
+ if sys.platform == "win32":
+ hierarchy[_io._IOBase][_io._RawIOBase].add(_io._WindowsConsoleIO)
+
+ recursive_check(hierarchy)
+
+ def test_subclassing(self):
+ _io = self._io
+ dataset = {k: True for k in self.types}
+ dataset[_io._BytesIOBuffer] = False
+
+ for tp, is_basetype in dataset.items():
+ with self.subTest(tp=tp, is_basetype=is_basetype):
+ name = f"{tp.__name__}_subclass"
+ bases = (tp,)
+ if is_basetype:
+ _ = type(name, bases, {})
+ else:
+ msg = "not an acceptable base type"
+ with self.assertRaisesRegex(TypeError, msg):
+ _ = type(name, bases, {})
+
+ def test_disallow_instantiation(self):
+ _io = self._io
+ support.check_disallow_instantiation(self, _io._BytesIOBuffer)
+
class PyIOTest(IOTest):
pass
CIncrementalNewlineDecoderTest, PyIncrementalNewlineDecoderTest,
CTextIOWrapperTest, PyTextIOWrapperTest,
CMiscIOTest, PyMiscIOTest,
- CSignalsTest, PySignalsTest,
+ CSignalsTest, PySignalsTest, TestIOCTypes,
)
# Put the namespaces of the IO module we are testing and some useful mock
#define PY_SSIZE_T_CLEAN
#include "Python.h"
#include "_iomodule.h"
-#include "pycore_moduleobject.h" // _PyModule_GetState()
#include "pycore_pystate.h" // _PyInterpreterState_GET()
#ifdef HAVE_SYS_TYPES_H
}
/* Create the Raw file stream */
+ _PyIO_State *state = get_io_state(module);
{
- PyObject *RawIO_class = (PyObject *)&PyFileIO_Type;
+ PyObject *RawIO_class = (PyObject *)state->PyFileIO_Type;
#ifdef MS_WINDOWS
const PyConfig *config = _Py_GetConfig();
if (!config->legacy_windows_stdio && _PyIO_get_console_type(path_or_fd) != '\0') {
{
PyObject *Buffered_class;
- if (updating)
- Buffered_class = (PyObject *)&PyBufferedRandom_Type;
- else if (creating || writing || appending)
- Buffered_class = (PyObject *)&PyBufferedWriter_Type;
- else if (reading)
- Buffered_class = (PyObject *)&PyBufferedReader_Type;
+ if (updating) {
+ Buffered_class = (PyObject *)state->PyBufferedRandom_Type;
+ }
+ else if (creating || writing || appending) {
+ Buffered_class = (PyObject *)state->PyBufferedWriter_Type;
+ }
+ else if (reading) {
+ Buffered_class = (PyObject *)state->PyBufferedReader_Type;
+ }
else {
PyErr_Format(PyExc_ValueError,
"unknown mode: '%s'", mode);
}
/* wraps into a TextIOWrapper */
- wrapper = PyObject_CallFunction((PyObject *)&PyTextIOWrapper_Type,
+ wrapper = PyObject_CallFunction((PyObject *)state->PyTextIOWrapper_Type,
"OsssO",
buffer,
encoding, errors, newline,
return result;
}
-static inline _PyIO_State*
-get_io_state(PyObject *module)
-{
- void *state = _PyModule_GetState(module);
- assert(state != NULL);
- return (_PyIO_State *)state;
-}
-
_PyIO_State *
_PyIO_get_module_state(void)
{
return 0;
Py_VISIT(state->locale_module);
Py_VISIT(state->unsupported_operation);
+
+ Py_VISIT(state->PyBufferedRWPair_Type);
+ Py_VISIT(state->PyBufferedRandom_Type);
+ Py_VISIT(state->PyBufferedReader_Type);
+ Py_VISIT(state->PyBufferedWriter_Type);
+ Py_VISIT(state->PyBytesIO_Type);
+ Py_VISIT(state->PyFileIO_Type);
+ Py_VISIT(state->PyStringIO_Type);
+ Py_VISIT(state->PyTextIOWrapper_Type);
return 0;
}
if (state->locale_module != NULL)
Py_CLEAR(state->locale_module);
Py_CLEAR(state->unsupported_operation);
+
+ Py_CLEAR(state->PyBufferedRWPair_Type);
+ Py_CLEAR(state->PyBufferedRandom_Type);
+ Py_CLEAR(state->PyBufferedReader_Type);
+ Py_CLEAR(state->PyBufferedWriter_Type);
+ Py_CLEAR(state->PyBytesIO_Type);
+ Py_CLEAR(state->PyFileIO_Type);
+ Py_CLEAR(state->PyStringIO_Type);
+ Py_CLEAR(state->PyTextIOWrapper_Type);
return 0;
}
* Module definition
*/
+#define clinic_state() (get_io_state(module))
#include "clinic/_iomodule.c.h"
+#undef clinic_state
static PyMethodDef module_methods[] = {
_IO_OPEN_METHODDEF
&PyRawIOBase_Type,
&PyTextIOBase_Type,
- // PyBufferedIOBase_Type(PyIOBase_Type) subclasses
- &PyBytesIO_Type,
- &PyBufferedReader_Type,
- &PyBufferedWriter_Type,
- &PyBufferedRWPair_Type,
- &PyBufferedRandom_Type,
-
// PyRawIOBase_Type(PyIOBase_Type) subclasses
- &PyFileIO_Type,
&_PyBytesIOBuffer_Type,
#ifdef MS_WINDOWS
&PyWindowsConsoleIO_Type,
#endif
-
- // PyTextIOBase_Type(PyIOBase_Type) subclasses
- &PyStringIO_Type,
- &PyTextIOWrapper_Type,
};
}
}
+#define ADD_TYPE(module, type, spec, base) \
+do { \
+ type = (PyTypeObject *)PyType_FromModuleAndSpec(module, spec, \
+ (PyObject *)base); \
+ if (type == NULL) { \
+ goto fail; \
+ } \
+ if (PyModule_AddType(module, type) < 0) { \
+ goto fail; \
+ } \
+} while (0)
PyMODINIT_FUNC
PyInit__io(void)
}
// Set type base classes
- PyFileIO_Type.tp_base = &PyRawIOBase_Type;
- PyBytesIO_Type.tp_base = &PyBufferedIOBase_Type;
- PyStringIO_Type.tp_base = &PyTextIOBase_Type;
#ifdef MS_WINDOWS
PyWindowsConsoleIO_Type.tp_base = &PyRawIOBase_Type;
#endif
- PyBufferedReader_Type.tp_base = &PyBufferedIOBase_Type;
- PyBufferedWriter_Type.tp_base = &PyBufferedIOBase_Type;
- PyBufferedRWPair_Type.tp_base = &PyBufferedIOBase_Type;
- PyBufferedRandom_Type.tp_base = &PyBufferedIOBase_Type;
- PyTextIOWrapper_Type.tp_base = &PyTextIOBase_Type;
// Add types
for (size_t i=0; i < Py_ARRAY_LENGTH(static_types); i++) {
}
}
+ // PyBufferedIOBase_Type(PyIOBase_Type) subclasses
+ ADD_TYPE(m, state->PyBytesIO_Type, &bytesio_spec, &PyBufferedIOBase_Type);
+ ADD_TYPE(m, state->PyBufferedWriter_Type, &bufferedwriter_spec,
+ &PyBufferedIOBase_Type);
+ ADD_TYPE(m, state->PyBufferedReader_Type, &bufferedreader_spec,
+ &PyBufferedIOBase_Type);
+ ADD_TYPE(m, state->PyBufferedRWPair_Type, &bufferedrwpair_spec,
+ &PyBufferedIOBase_Type);
+ ADD_TYPE(m, state->PyBufferedRandom_Type, &bufferedrandom_spec,
+ &PyBufferedIOBase_Type);
+
+ // PyRawIOBase_Type(PyIOBase_Type) subclasses
+ ADD_TYPE(m, state->PyFileIO_Type, &fileio_spec, &PyRawIOBase_Type);
+
+ // PyTextIOBase_Type(PyIOBase_Type) subclasses
+ ADD_TYPE(m, state->PyStringIO_Type, &stringio_spec, &PyTextIOBase_Type);
+ ADD_TYPE(m, state->PyTextIOWrapper_Type, &textiowrapper_spec,
+ &PyTextIOBase_Type);
+
state->initialized = 1;
return m;
#include "exports.h"
+#include "pycore_moduleobject.h" // _PyModule_GetState()
+#include "structmember.h"
+
/* ABCs */
extern PyTypeObject PyIOBase_Type;
extern PyTypeObject PyRawIOBase_Type;
extern PyTypeObject PyTextIOBase_Type;
/* Concrete classes */
-extern PyTypeObject PyFileIO_Type;
-extern PyTypeObject PyBytesIO_Type;
-extern PyTypeObject PyStringIO_Type;
-extern PyTypeObject PyBufferedReader_Type;
-extern PyTypeObject PyBufferedWriter_Type;
-extern PyTypeObject PyBufferedRWPair_Type;
-extern PyTypeObject PyBufferedRandom_Type;
-extern PyTypeObject PyTextIOWrapper_Type;
extern PyTypeObject PyIncrementalNewlineDecoder_Type;
+/* Type specs */
+extern PyType_Spec bufferedrandom_spec;
+extern PyType_Spec bufferedreader_spec;
+extern PyType_Spec bufferedrwpair_spec;
+extern PyType_Spec bufferedwriter_spec;
+extern PyType_Spec bytesio_spec;
+extern PyType_Spec fileio_spec;
+extern PyType_Spec stringio_spec;
+extern PyType_Spec textiowrapper_spec;
+
#ifdef MS_WINDOWS
extern PyTypeObject PyWindowsConsoleIO_Type;
#endif /* MS_WINDOWS */
PyObject *locale_module;
PyObject *unsupported_operation;
+
+ /* Types */
+ PyTypeObject *PyBufferedRWPair_Type;
+ PyTypeObject *PyBufferedRandom_Type;
+ PyTypeObject *PyBufferedReader_Type;
+ PyTypeObject *PyBufferedWriter_Type;
+ PyTypeObject *PyBytesIO_Type;
+ PyTypeObject *PyFileIO_Type;
+ PyTypeObject *PyStringIO_Type;
+ PyTypeObject *PyTextIOWrapper_Type;
} _PyIO_State;
#define IO_MOD_STATE(mod) ((_PyIO_State *)PyModule_GetState(mod))
#define IO_STATE() _PyIO_get_module_state()
+static inline _PyIO_State *
+get_io_state(PyObject *module)
+{
+ void *state = _PyModule_GetState(module);
+ assert(state != NULL);
+ return (_PyIO_State *)state;
+}
+
+static inline _PyIO_State *
+find_io_state_by_def(PyTypeObject *type)
+{
+ PyObject *mod = PyType_GetModuleByDef(type, &_PyIO_Module);
+ assert(mod != NULL);
+ return get_io_state(mod);
+}
+
extern _PyIO_State *_PyIO_get_module_state(void);
#ifdef MS_WINDOWS
module _io
class _io._BufferedIOBase "PyObject *" "&PyBufferedIOBase_Type"
class _io._Buffered "buffered *" "&PyBufferedIOBase_Type"
-class _io.BufferedReader "buffered *" "&PyBufferedReader_Type"
-class _io.BufferedWriter "buffered *" "&PyBufferedWriter_Type"
-class _io.BufferedRWPair "rwpair *" "&PyBufferedRWPair_Type"
-class _io.BufferedRandom "buffered *" "&PyBufferedRandom_Type"
+class _io.BufferedReader "buffered *" "clinic_state()->PyBufferedReader_Type"
+class _io.BufferedWriter "buffered *" "clinic_state()->PyBufferedWriter_Type"
+class _io.BufferedRWPair "rwpair *" "clinic_state()->PyBufferedRWPair_Type"
+class _io.BufferedRandom "buffered *" "clinic_state()->PyBufferedRandom_Type"
[clinic start generated code]*/
-/*[clinic end generated code: output=da39a3ee5e6b4b0d input=59460b9c5639984d]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=abd685b9d94b9888]*/
/*
* BufferedIOBase class, inherits from IOBase.
static void
buffered_dealloc(buffered *self)
{
+ PyTypeObject *tp = Py_TYPE(self);
self->finalizing = 1;
if (_PyIOBase_finalize((PyObject *) self) < 0)
return;
self->lock = NULL;
}
Py_CLEAR(self->dict);
- Py_TYPE(self)->tp_free((PyObject *)self);
+ tp->tp_free((PyObject *)self);
+ Py_DECREF(tp);
}
static PyObject *
static int
buffered_traverse(buffered *self, visitproc visit, void *arg)
{
+ Py_VISIT(Py_TYPE(self));
Py_VISIT(self->raw);
Py_VISIT(self->dict);
return 0;
CHECK_INITIALIZED(self);
+ _PyIO_State *state = find_io_state_by_def(Py_TYPE(self));
tp = Py_TYPE(self);
- if (tp == &PyBufferedReader_Type ||
- tp == &PyBufferedRandom_Type) {
+ if (Py_IS_TYPE(tp, state->PyBufferedReader_Type) ||
+ Py_IS_TYPE(tp, state->PyBufferedRandom_Type))
+ {
/* Skip method call overhead for speed */
line = _buffered_readline(self, -1);
}
return -1;
_bufferedreader_reset_buf(self);
- self->fast_closed_checks = (Py_IS_TYPE(self, &PyBufferedReader_Type) &&
- Py_IS_TYPE(raw, &PyFileIO_Type));
+ _PyIO_State *state = find_io_state_by_def(Py_TYPE(self));
+ self->fast_closed_checks = (
+ Py_IS_TYPE(self, state->PyBufferedReader_Type) &&
+ Py_IS_TYPE(raw, state->PyFileIO_Type)
+ );
self->ok = 1;
return 0;
_bufferedwriter_reset_buf(self);
self->pos = 0;
- self->fast_closed_checks = (Py_IS_TYPE(self, &PyBufferedWriter_Type) &&
- Py_IS_TYPE(raw, &PyFileIO_Type));
+ _PyIO_State *state = find_io_state_by_def(Py_TYPE(self));
+ self->fast_closed_checks = (
+ Py_IS_TYPE(self, state->PyBufferedWriter_Type) &&
+ Py_IS_TYPE(raw, state->PyFileIO_Type)
+ );
self->ok = 1;
return 0;
if (_PyIOBase_check_writable(writer, Py_True) == NULL)
return -1;
+ _PyIO_State *state = find_io_state_by_def(Py_TYPE(self));
self->reader = (buffered *) PyObject_CallFunction(
- (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
+ (PyObject *)state->PyBufferedReader_Type,
+ "On", reader, buffer_size);
if (self->reader == NULL)
return -1;
self->writer = (buffered *) PyObject_CallFunction(
- (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
+ (PyObject *)state->PyBufferedWriter_Type,
+ "On", writer, buffer_size);
if (self->writer == NULL) {
Py_CLEAR(self->reader);
return -1;
static int
bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
{
+ Py_VISIT(Py_TYPE(self));
Py_VISIT(self->dict);
return 0;
}
static void
bufferedrwpair_dealloc(rwpair *self)
{
+ PyTypeObject *tp = Py_TYPE(self);
_PyObject_GC_UNTRACK(self);
if (self->weakreflist != NULL)
PyObject_ClearWeakRefs((PyObject *)self);
Py_CLEAR(self->reader);
Py_CLEAR(self->writer);
Py_CLEAR(self->dict);
- Py_TYPE(self)->tp_free((PyObject *) self);
+ tp->tp_free((PyObject *) self);
+ Py_DECREF(tp);
}
static PyObject *
_bufferedwriter_reset_buf(self);
self->pos = 0;
- self->fast_closed_checks = (Py_IS_TYPE(self, &PyBufferedRandom_Type) &&
- Py_IS_TYPE(raw, &PyFileIO_Type));
+ _PyIO_State *state = find_io_state_by_def(Py_TYPE(self));
+ self->fast_closed_checks = (Py_IS_TYPE(self, state->PyBufferedRandom_Type) &&
+ Py_IS_TYPE(raw, state->PyFileIO_Type));
self->ok = 1;
return 0;
}
+#define clinic_state() (find_io_state_by_def(Py_TYPE(self)))
#include "clinic/bufferedio.c.h"
+#undef clinic_state
static PyMethodDef bufferediobase_methods[] = {
static PyMemberDef bufferedreader_members[] = {
{"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
{"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
+ {"__weaklistoffset__", T_PYSSIZET, offsetof(buffered, weakreflist), READONLY},
+ {"__dictoffset__", T_PYSSIZET, offsetof(buffered, dict), READONLY},
{NULL}
};
};
-PyTypeObject PyBufferedReader_Type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "_io.BufferedReader", /*tp_name*/
- sizeof(buffered), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)buffered_dealloc, /*tp_dealloc*/
- 0, /*tp_vectorcall_offset*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_as_async*/
- (reprfunc)buffered_repr, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
- | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
- _io_BufferedReader___init____doc__, /* tp_doc */
- (traverseproc)buffered_traverse, /* tp_traverse */
- (inquiry)buffered_clear, /* tp_clear */
- 0, /* tp_richcompare */
- offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
- 0, /* tp_iter */
- (iternextfunc)buffered_iternext, /* tp_iternext */
- bufferedreader_methods, /* tp_methods */
- bufferedreader_members, /* tp_members */
- bufferedreader_getset, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- offsetof(buffered, dict), /* tp_dictoffset */
- _io_BufferedReader___init__, /* tp_init */
- 0, /* tp_alloc */
- PyType_GenericNew, /* tp_new */
- 0, /* tp_free */
- 0, /* tp_is_gc */
- 0, /* tp_bases */
- 0, /* tp_mro */
- 0, /* tp_cache */
- 0, /* tp_subclasses */
- 0, /* tp_weaklist */
- 0, /* tp_del */
- 0, /* tp_version_tag */
- 0, /* tp_finalize */
+static PyType_Slot bufferedreader_slots[] = {
+ {Py_tp_dealloc, buffered_dealloc},
+ {Py_tp_repr, buffered_repr},
+ {Py_tp_doc, (void *)_io_BufferedReader___init____doc__},
+ {Py_tp_traverse, buffered_traverse},
+ {Py_tp_clear, buffered_clear},
+ {Py_tp_iternext, buffered_iternext},
+ {Py_tp_methods, bufferedreader_methods},
+ {Py_tp_members, bufferedreader_members},
+ {Py_tp_getset, bufferedreader_getset},
+ {Py_tp_init, _io_BufferedReader___init__},
+ {0, NULL},
};
+PyType_Spec bufferedreader_spec = {
+ .name = "_io.BufferedReader",
+ .basicsize = sizeof(buffered),
+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_IMMUTABLETYPE),
+ .slots = bufferedreader_slots,
+};
static PyMethodDef bufferedwriter_methods[] = {
/* BufferedIOMixin methods */
static PyMemberDef bufferedwriter_members[] = {
{"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
{"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
+ {"__weaklistoffset__", T_PYSSIZET, offsetof(buffered, weakreflist), READONLY},
+ {"__dictoffset__", T_PYSSIZET, offsetof(buffered, dict), READONLY},
{NULL}
};
};
-PyTypeObject PyBufferedWriter_Type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "_io.BufferedWriter", /*tp_name*/
- sizeof(buffered), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)buffered_dealloc, /*tp_dealloc*/
- 0, /*tp_vectorcall_offset*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_as_async*/
- (reprfunc)buffered_repr, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
- | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
- _io_BufferedWriter___init____doc__, /* tp_doc */
- (traverseproc)buffered_traverse, /* tp_traverse */
- (inquiry)buffered_clear, /* tp_clear */
- 0, /* tp_richcompare */
- offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
- 0, /* tp_iter */
- 0, /* tp_iternext */
- bufferedwriter_methods, /* tp_methods */
- bufferedwriter_members, /* tp_members */
- bufferedwriter_getset, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- offsetof(buffered, dict), /* tp_dictoffset */
- _io_BufferedWriter___init__, /* tp_init */
- 0, /* tp_alloc */
- PyType_GenericNew, /* tp_new */
- 0, /* tp_free */
- 0, /* tp_is_gc */
- 0, /* tp_bases */
- 0, /* tp_mro */
- 0, /* tp_cache */
- 0, /* tp_subclasses */
- 0, /* tp_weaklist */
- 0, /* tp_del */
- 0, /* tp_version_tag */
- 0, /* tp_finalize */
+static PyType_Slot bufferedwriter_slots[] = {
+ {Py_tp_dealloc, buffered_dealloc},
+ {Py_tp_repr, buffered_repr},
+ {Py_tp_doc, (void *)_io_BufferedWriter___init____doc__},
+ {Py_tp_traverse, buffered_traverse},
+ {Py_tp_clear, buffered_clear},
+ {Py_tp_methods, bufferedwriter_methods},
+ {Py_tp_members, bufferedwriter_members},
+ {Py_tp_getset, bufferedwriter_getset},
+ {Py_tp_init, _io_BufferedWriter___init__},
+ {0, NULL},
};
+PyType_Spec bufferedwriter_spec = {
+ .name = "_io.BufferedWriter",
+ .basicsize = sizeof(buffered),
+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_IMMUTABLETYPE),
+ .slots = bufferedwriter_slots,
+};
static PyMethodDef bufferedrwpair_methods[] = {
{"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
{NULL, NULL}
};
+static PyMemberDef bufferedrwpair_members[] = {
+ {"__weaklistoffset__", T_PYSSIZET, offsetof(rwpair, weakreflist), READONLY},
+ {"__dictoffset__", T_PYSSIZET, offsetof(rwpair, dict), READONLY},
+ {NULL}
+};
+
static PyGetSetDef bufferedrwpair_getset[] = {
{"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
{NULL}
};
-PyTypeObject PyBufferedRWPair_Type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "_io.BufferedRWPair", /*tp_name*/
- sizeof(rwpair), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
- 0, /*tp_vectorcall_offset*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_as_async*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
- | Py_TPFLAGS_HAVE_GC, /* tp_flags */
- _io_BufferedRWPair___init____doc__, /* tp_doc */
- (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
- (inquiry)bufferedrwpair_clear, /* tp_clear */
- 0, /* tp_richcompare */
- offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
- 0, /* tp_iter */
- 0, /* tp_iternext */
- bufferedrwpair_methods, /* tp_methods */
- 0, /* tp_members */
- bufferedrwpair_getset, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- offsetof(rwpair, dict), /* tp_dictoffset */
- _io_BufferedRWPair___init__, /* tp_init */
- 0, /* tp_alloc */
- PyType_GenericNew, /* tp_new */
- 0, /* tp_free */
- 0, /* tp_is_gc */
- 0, /* tp_bases */
- 0, /* tp_mro */
- 0, /* tp_cache */
- 0, /* tp_subclasses */
- 0, /* tp_weaklist */
- 0, /* tp_del */
- 0, /* tp_version_tag */
- 0, /* tp_finalize */
+static PyType_Slot bufferedrwpair_slots[] = {
+ {Py_tp_dealloc, bufferedrwpair_dealloc},
+ {Py_tp_doc, (void *)_io_BufferedRWPair___init____doc__},
+ {Py_tp_traverse, bufferedrwpair_traverse},
+ {Py_tp_clear, bufferedrwpair_clear},
+ {Py_tp_methods, bufferedrwpair_methods},
+ {Py_tp_members, bufferedrwpair_members},
+ {Py_tp_getset, bufferedrwpair_getset},
+ {Py_tp_init, _io_BufferedRWPair___init__},
+ {0, NULL},
+};
+
+PyType_Spec bufferedrwpair_spec = {
+ .name = "_io.BufferedRWPair",
+ .basicsize = sizeof(rwpair),
+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_IMMUTABLETYPE),
+ .slots = bufferedrwpair_slots,
};
static PyMemberDef bufferedrandom_members[] = {
{"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
{"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
+ {"__weaklistoffset__", T_PYSSIZET, offsetof(buffered, weakreflist), READONLY},
+ {"__dictoffset__", T_PYSSIZET, offsetof(buffered, dict), READONLY},
{NULL}
};
};
-PyTypeObject PyBufferedRandom_Type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "_io.BufferedRandom", /*tp_name*/
- sizeof(buffered), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)buffered_dealloc, /*tp_dealloc*/
- 0, /*tp_vectorcall_offset*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_as_async*/
- (reprfunc)buffered_repr, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
- | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
- _io_BufferedRandom___init____doc__, /* tp_doc */
- (traverseproc)buffered_traverse, /* tp_traverse */
- (inquiry)buffered_clear, /* tp_clear */
- 0, /* tp_richcompare */
- offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
- 0, /* tp_iter */
- (iternextfunc)buffered_iternext, /* tp_iternext */
- bufferedrandom_methods, /* tp_methods */
- bufferedrandom_members, /* tp_members */
- bufferedrandom_getset, /* tp_getset */
- 0, /* tp_base */
- 0, /*tp_dict*/
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- offsetof(buffered, dict), /*tp_dictoffset*/
- _io_BufferedRandom___init__, /* tp_init */
- 0, /* tp_alloc */
- PyType_GenericNew, /* tp_new */
- 0, /* tp_free */
- 0, /* tp_is_gc */
- 0, /* tp_bases */
- 0, /* tp_mro */
- 0, /* tp_cache */
- 0, /* tp_subclasses */
- 0, /* tp_weaklist */
- 0, /* tp_del */
- 0, /* tp_version_tag */
- 0, /* tp_finalize */
+static PyType_Slot bufferedrandom_slots[] = {
+ {Py_tp_dealloc, buffered_dealloc},
+ {Py_tp_repr, buffered_repr},
+ {Py_tp_doc, (void *)_io_BufferedRandom___init____doc__},
+ {Py_tp_traverse, buffered_traverse},
+ {Py_tp_clear, buffered_clear},
+ {Py_tp_iternext, buffered_iternext},
+ {Py_tp_methods, bufferedrandom_methods},
+ {Py_tp_members, bufferedrandom_members},
+ {Py_tp_getset, bufferedrandom_getset},
+ {Py_tp_init, _io_BufferedRandom___init__},
+ {0, NULL},
+};
+
+PyType_Spec bufferedrandom_spec = {
+ .name = "_io.BufferedRandom",
+ .basicsize = sizeof(buffered),
+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_IMMUTABLETYPE),
+ .slots = bufferedrandom_slots,
};
/*[clinic input]
module _io
-class _io.BytesIO "bytesio *" "&PyBytesIO_Type"
+class _io.BytesIO "bytesio *" "clinic_state()->PyBytesIO_Type"
[clinic start generated code]*/
-/*[clinic end generated code: output=da39a3ee5e6b4b0d input=7f50ec034f5c0b26]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=48ede2f330f847c3]*/
typedef struct {
PyObject_HEAD
static void
bytesio_dealloc(bytesio *self)
{
+ PyTypeObject *tp = Py_TYPE(self);
_PyObject_GC_UNTRACK(self);
if (self->exports > 0) {
PyErr_SetString(PyExc_SystemError,
Py_CLEAR(self->dict);
if (self->weakreflist != NULL)
PyObject_ClearWeakRefs((PyObject *) self);
- Py_TYPE(self)->tp_free(self);
+ tp->tp_free(self);
+ Py_DECREF(tp);
}
static PyObject *
static int
bytesio_traverse(bytesio *self, visitproc visit, void *arg)
{
+ Py_VISIT(Py_TYPE(self));
Py_VISIT(self->dict);
return 0;
}
}
+#define clinic_state() (find_io_state_by_def(Py_TYPE(self)))
#include "clinic/bytesio.c.h"
+#undef clinic_state
static PyGetSetDef bytesio_getsetlist[] = {
{"closed", (getter)bytesio_get_closed, NULL,
{NULL, NULL} /* sentinel */
};
-PyTypeObject PyBytesIO_Type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "_io.BytesIO", /*tp_name*/
- sizeof(bytesio), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)bytesio_dealloc, /*tp_dealloc*/
- 0, /*tp_vectorcall_offset*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_as_async*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash*/
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
- Py_TPFLAGS_HAVE_GC, /*tp_flags*/
- _io_BytesIO___init____doc__, /*tp_doc*/
- (traverseproc)bytesio_traverse, /*tp_traverse*/
- (inquiry)bytesio_clear, /*tp_clear*/
- 0, /*tp_richcompare*/
- offsetof(bytesio, weakreflist), /*tp_weaklistoffset*/
- PyObject_SelfIter, /*tp_iter*/
- (iternextfunc)bytesio_iternext, /*tp_iternext*/
- bytesio_methods, /*tp_methods*/
- 0, /*tp_members*/
- bytesio_getsetlist, /*tp_getset*/
- 0, /*tp_base*/
- 0, /*tp_dict*/
- 0, /*tp_descr_get*/
- 0, /*tp_descr_set*/
- offsetof(bytesio, dict), /*tp_dictoffset*/
- _io_BytesIO___init__, /*tp_init*/
- 0, /*tp_alloc*/
- bytesio_new, /*tp_new*/
+static PyMemberDef bytesio_members[] = {
+ {"__weaklistoffset__", T_PYSSIZET, offsetof(bytesio, weakreflist), READONLY},
+ {"__dictoffset__", T_PYSSIZET, offsetof(bytesio, dict), READONLY},
+ {NULL}
};
+static PyType_Slot bytesio_slots[] = {
+ {Py_tp_dealloc, bytesio_dealloc},
+ {Py_tp_doc, (void *)_io_BytesIO___init____doc__},
+ {Py_tp_traverse, bytesio_traverse},
+ {Py_tp_clear, bytesio_clear},
+ {Py_tp_iter, PyObject_SelfIter},
+ {Py_tp_iternext, bytesio_iternext},
+ {Py_tp_methods, bytesio_methods},
+ {Py_tp_members, bytesio_members},
+ {Py_tp_getset, bytesio_getsetlist},
+ {Py_tp_init, _io_BytesIO___init__},
+ {Py_tp_new, bytesio_new},
+ {0, NULL},
+};
+
+PyType_Spec bytesio_spec = {
+ .name = "_io.BytesIO",
+ .basicsize = sizeof(bytesio),
+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_IMMUTABLETYPE),
+ .slots = bytesio_slots,
+};
/*
* Implementation of the small intermediate object used by getbuffer().
_io_BufferedRWPair___init__(PyObject *self, PyObject *args, PyObject *kwargs)
{
int return_value = -1;
- PyTypeObject *base_tp = &PyBufferedRWPair_Type;
+ PyTypeObject *base_tp = clinic_state()->PyBufferedRWPair_Type;
PyObject *reader;
PyObject *writer;
Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE;
exit:
return return_value;
}
-/*[clinic end generated code: output=953f1577e96e8d86 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=8412b10c04259bb8 input=a9049054013a1b77]*/
/*[clinic input]
module _io
-class _io.FileIO "fileio *" "&PyFileIO_Type"
+class _io.FileIO "fileio *" "clinic_state()->PyFileIO_Type"
[clinic start generated code]*/
-/*[clinic end generated code: output=da39a3ee5e6b4b0d input=1c77708b41fda70c]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ac25ec278f4d6703]*/
typedef struct {
PyObject_HEAD
PyObject *dict;
} fileio;
-PyTypeObject PyFileIO_Type;
-
-#define PyFileIO_Check(op) (PyObject_TypeCheck((op), &PyFileIO_Type))
+#define PyFileIO_Check(state, op) (PyObject_TypeCheck((op), state->PyFileIO_Type))
/* Forward declarations */
static PyObject* portable_lseek(fileio *self, PyObject *posobj, int whence, bool suppress_pipe_error);
int fstat_result;
int async_err = 0;
- assert(PyFileIO_Check(self));
+#ifdef Py_DEBUG
+ _PyIO_State *state = find_io_state_by_def(Py_TYPE(self));
+ assert(PyFileIO_Check(state, self));
+#endif
if (self->fd >= 0) {
if (self->closefd) {
/* Have to close the existing file first. */
static int
fileio_traverse(fileio *self, visitproc visit, void *arg)
{
+ Py_VISIT(Py_TYPE(self));
Py_VISIT(self->dict);
return 0;
}
static void
fileio_dealloc(fileio *self)
{
+ PyTypeObject *tp = Py_TYPE(self);
self->finalizing = 1;
if (_PyIOBase_finalize((PyObject *) self) < 0)
return;
if (self->weakreflist != NULL)
PyObject_ClearWeakRefs((PyObject *) self);
Py_CLEAR(self->dict);
- Py_TYPE(self)->tp_free((PyObject *)self);
+ tp->tp_free((PyObject *)self);
+ Py_DECREF(tp);
}
static PyObject *
static PyMemberDef fileio_members[] = {
{"_blksize", T_UINT, offsetof(fileio, blksize), 0},
{"_finalizing", T_BOOL, offsetof(fileio, finalizing), 0},
+ {"__weaklistoffset__", T_PYSSIZET, offsetof(fileio, weakreflist), READONLY},
+ {"__dictoffset__", T_PYSSIZET, offsetof(fileio, dict), READONLY},
{NULL}
};
-PyTypeObject PyFileIO_Type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "_io.FileIO",
- sizeof(fileio),
- 0,
- (destructor)fileio_dealloc, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_as_async */
- (reprfunc)fileio_repr, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- PyObject_GenericGetAttr, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
- | Py_TPFLAGS_HAVE_GC, /* tp_flags */
- _io_FileIO___init____doc__, /* tp_doc */
- (traverseproc)fileio_traverse, /* tp_traverse */
- (inquiry)fileio_clear, /* tp_clear */
- 0, /* tp_richcompare */
- offsetof(fileio, weakreflist), /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- fileio_methods, /* tp_methods */
- fileio_members, /* tp_members */
- fileio_getsetlist, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- offsetof(fileio, dict), /* tp_dictoffset */
- _io_FileIO___init__, /* tp_init */
- PyType_GenericAlloc, /* tp_alloc */
- fileio_new, /* tp_new */
- PyObject_GC_Del, /* tp_free */
- 0, /* tp_is_gc */
- 0, /* tp_bases */
- 0, /* tp_mro */
- 0, /* tp_cache */
- 0, /* tp_subclasses */
- 0, /* tp_weaklist */
- 0, /* tp_del */
- 0, /* tp_version_tag */
- 0, /* tp_finalize */
+static PyType_Slot fileio_slots[] = {
+ {Py_tp_dealloc, fileio_dealloc},
+ {Py_tp_repr, fileio_repr},
+ {Py_tp_doc, (void *)_io_FileIO___init____doc__},
+ {Py_tp_traverse, fileio_traverse},
+ {Py_tp_clear, fileio_clear},
+ {Py_tp_methods, fileio_methods},
+ {Py_tp_members, fileio_members},
+ {Py_tp_getset, fileio_getsetlist},
+ {Py_tp_init, _io_FileIO___init__},
+ {Py_tp_new, fileio_new},
+ {0, NULL},
+};
+
+PyType_Spec fileio_spec = {
+ .name = "_io.FileIO",
+ .basicsize = sizeof(fileio),
+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_IMMUTABLETYPE),
+ .slots = fileio_slots,
};
/*[clinic input]
module _io
-class _io.StringIO "stringio *" "&PyStringIO_Type"
+class _io.StringIO "stringio *" "clinic_state()->PyStringIO_Type"
[clinic start generated code]*/
-/*[clinic end generated code: output=da39a3ee5e6b4b0d input=c17bc0f42165cd7d]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=2693eada0658d470]*/
typedef struct {
PyObject_HEAD
PyObject *dict;
PyObject *weakreflist;
+ _PyIO_State *module_state;
} stringio;
static int _io_StringIO___init__(PyObject *self, PyObject *args, PyObject *kwargs);
CHECK_CLOSED(self);
ENSURE_REALIZED(self);
- if (Py_IS_TYPE(self, &PyStringIO_Type)) {
+ if (Py_IS_TYPE(self, self->module_state->PyStringIO_Type)) {
/* Skip method call overhead for speed */
line = _stringio_readline(self, -1);
}
static int
stringio_traverse(stringio *self, visitproc visit, void *arg)
{
+ Py_VISIT(Py_TYPE(self));
Py_VISIT(self->dict);
return 0;
}
static void
stringio_dealloc(stringio *self)
{
+ PyTypeObject *tp = Py_TYPE(self);
_PyObject_GC_UNTRACK(self);
self->ok = 0;
if (self->buf) {
Py_CLEAR(self->writenl);
Py_CLEAR(self->decoder);
Py_CLEAR(self->dict);
- if (self->weakreflist != NULL)
+ if (self->weakreflist != NULL) {
PyObject_ClearWeakRefs((PyObject *) self);
- Py_TYPE(self)->tp_free(self);
+ }
+ tp->tp_free(self);
+ Py_DECREF(tp);
}
static PyObject *
self->state = STATE_ACCUMULATING;
}
self->pos = 0;
-
+ self->module_state = find_io_state_by_def(Py_TYPE(self));
self->closed = 0;
self->ok = 1;
return 0;
return PyObject_GetAttr(self->decoder, &_Py_ID(newlines));
}
+#define clinic_state() (find_io_state_by_def(Py_TYPE(self)))
#include "clinic/stringio.c.h"
+#undef clinic_state
static struct PyMethodDef stringio_methods[] = {
_IO_STRINGIO_CLOSE_METHODDEF
{NULL}
};
-PyTypeObject PyStringIO_Type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "_io.StringIO", /*tp_name*/
- sizeof(stringio), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)stringio_dealloc, /*tp_dealloc*/
- 0, /*tp_vectorcall_offset*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_as_async*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash*/
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
- | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
- _io_StringIO___init____doc__, /*tp_doc*/
- (traverseproc)stringio_traverse, /*tp_traverse*/
- (inquiry)stringio_clear, /*tp_clear*/
- 0, /*tp_richcompare*/
- offsetof(stringio, weakreflist), /*tp_weaklistoffset*/
- 0, /*tp_iter*/
- (iternextfunc)stringio_iternext, /*tp_iternext*/
- stringio_methods, /*tp_methods*/
- 0, /*tp_members*/
- stringio_getset, /*tp_getset*/
- 0, /*tp_base*/
- 0, /*tp_dict*/
- 0, /*tp_descr_get*/
- 0, /*tp_descr_set*/
- offsetof(stringio, dict), /*tp_dictoffset*/
- _io_StringIO___init__, /*tp_init*/
- 0, /*tp_alloc*/
- stringio_new, /*tp_new*/
+static struct PyMemberDef stringio_members[] = {
+ {"__weaklistoffset__", T_PYSSIZET, offsetof(stringio, weakreflist), READONLY},
+ {"__dictoffset__", T_PYSSIZET, offsetof(stringio, dict), READONLY},
+ {NULL},
+};
+
+static PyType_Slot stringio_slots[] = {
+ {Py_tp_dealloc, stringio_dealloc},
+ {Py_tp_doc, (void *)_io_StringIO___init____doc__},
+ {Py_tp_traverse, stringio_traverse},
+ {Py_tp_clear, stringio_clear},
+ {Py_tp_iternext, stringio_iternext},
+ {Py_tp_methods, stringio_methods},
+ {Py_tp_members, stringio_members},
+ {Py_tp_getset, stringio_getset},
+ {Py_tp_init, _io_StringIO___init__},
+ {Py_tp_new, stringio_new},
+ {0, NULL},
+};
+
+PyType_Spec stringio_spec = {
+ .name = "_io.StringIO",
+ .basicsize = sizeof(stringio),
+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_IMMUTABLETYPE),
+ .slots = stringio_slots,
};
/*[clinic input]
module _io
class _io.IncrementalNewlineDecoder "nldecoder_object *" "&PyIncrementalNewlineDecoder_Type"
-class _io.TextIOWrapper "textio *" "&TextIOWrapper_Type"
+class _io.TextIOWrapper "textio *" "clinic_state()->TextIOWrapper_Type"
[clinic start generated code]*/
-/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ed072384f8aada2c]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=d3f032e90f74c8f2]*/
/* TextIOBase */
PyObject *weakreflist;
PyObject *dict;
+
+ _PyIO_State *state;
} textio;
static void
/* Finished sorting out the codec details */
Py_CLEAR(codec_info);
- if (Py_IS_TYPE(buffer, &PyBufferedReader_Type) ||
- Py_IS_TYPE(buffer, &PyBufferedWriter_Type) ||
- Py_IS_TYPE(buffer, &PyBufferedRandom_Type))
+ _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))
{
if (_PyObject_LookupAttr(buffer, &_Py_ID(raw), &raw) < 0)
goto error;
/* Cache the raw FileIO object to speed up 'closed' checks */
if (raw != NULL) {
- if (Py_IS_TYPE(raw, &PyFileIO_Type))
+ if (Py_IS_TYPE(raw, state->PyFileIO_Type))
self->raw = raw;
else
Py_DECREF(raw);
goto error;
}
+ self->state = state;
self->ok = 1;
return 0;
static void
textiowrapper_dealloc(textio *self)
{
+ PyTypeObject *tp = Py_TYPE(self);
self->finalizing = 1;
if (_PyIOBase_finalize((PyObject *) self) < 0)
return;
if (self->weakreflist != NULL)
PyObject_ClearWeakRefs((PyObject *)self);
textiowrapper_clear(self);
- Py_TYPE(self)->tp_free((PyObject *)self);
+ tp->tp_free((PyObject *)self);
+ Py_DECREF(tp);
}
static int
textiowrapper_traverse(textio *self, visitproc visit, void *arg)
{
+ Py_VISIT(Py_TYPE(self));
Py_VISIT(self->buffer);
Py_VISIT(self->encoding);
Py_VISIT(self->encoder);
do { \
int r; \
PyObject *_res; \
- if (Py_IS_TYPE(self, &PyTextIOWrapper_Type)) { \
+ if (Py_IS_TYPE(self, self->state->PyTextIOWrapper_Type)) { \
if (self->raw != NULL) \
r = _PyFileIO_closed(self->raw); \
else { \
CHECK_ATTACHED(self);
self->telling = 0;
- if (Py_IS_TYPE(self, &PyTextIOWrapper_Type)) {
+ if (Py_IS_TYPE(self, self->state->PyTextIOWrapper_Type)) {
/* Skip method call overhead for speed */
line = _textiowrapper_readline(self, -1);
}
return 0;
}
+#define clinic_state() (find_io_state_by_def(Py_TYPE(self)))
#include "clinic/textio.c.h"
+#undef clinic_state
static PyMethodDef incrementalnewlinedecoder_methods[] = {
_IO_INCREMENTALNEWLINEDECODER_DECODE_METHODDEF
{"line_buffering", T_BOOL, offsetof(textio, line_buffering), READONLY},
{"write_through", T_BOOL, offsetof(textio, write_through), READONLY},
{"_finalizing", T_BOOL, offsetof(textio, finalizing), 0},
+ {"__weaklistoffset__", T_PYSSIZET, offsetof(textio, weakreflist), READONLY},
+ {"__dictoffset__", T_PYSSIZET, offsetof(textio, dict), READONLY},
{NULL}
};
{NULL}
};
-PyTypeObject PyTextIOWrapper_Type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "_io.TextIOWrapper", /*tp_name*/
- sizeof(textio), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)textiowrapper_dealloc, /*tp_dealloc*/
- 0, /*tp_vectorcall_offset*/
- 0, /*tp_getattr*/
- 0, /*tps_etattr*/
- 0, /*tp_as_async*/
- (reprfunc)textiowrapper_repr,/*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
- | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
- _io_TextIOWrapper___init____doc__, /* tp_doc */
- (traverseproc)textiowrapper_traverse, /* tp_traverse */
- (inquiry)textiowrapper_clear, /* tp_clear */
- 0, /* tp_richcompare */
- offsetof(textio, weakreflist), /*tp_weaklistoffset*/
- 0, /* tp_iter */
- (iternextfunc)textiowrapper_iternext, /* tp_iternext */
- textiowrapper_methods, /* tp_methods */
- textiowrapper_members, /* tp_members */
- textiowrapper_getset, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- offsetof(textio, dict), /*tp_dictoffset*/
- _io_TextIOWrapper___init__, /* tp_init */
- 0, /* tp_alloc */
- PyType_GenericNew, /* tp_new */
- 0, /* tp_free */
- 0, /* tp_is_gc */
- 0, /* tp_bases */
- 0, /* tp_mro */
- 0, /* tp_cache */
- 0, /* tp_subclasses */
- 0, /* tp_weaklist */
- 0, /* tp_del */
- 0, /* tp_version_tag */
- 0, /* tp_finalize */
+PyType_Slot textiowrapper_slots[] = {
+ {Py_tp_dealloc, textiowrapper_dealloc},
+ {Py_tp_repr, textiowrapper_repr},
+ {Py_tp_doc, (void *)_io_TextIOWrapper___init____doc__},
+ {Py_tp_traverse, textiowrapper_traverse},
+ {Py_tp_clear, textiowrapper_clear},
+ {Py_tp_iternext, textiowrapper_iternext},
+ {Py_tp_methods, textiowrapper_methods},
+ {Py_tp_members, textiowrapper_members},
+ {Py_tp_getset, textiowrapper_getset},
+ {Py_tp_init, _io_TextIOWrapper___init__},
+ {0, NULL},
+};
+
+PyType_Spec textiowrapper_spec = {
+ .name = "_io.TextIOWrapper",
+ .basicsize = sizeof(textio),
+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
+ Py_TPFLAGS_IMMUTABLETYPE),
+ .slots = textiowrapper_slots,
};
Modules/_collectionsmodule.c - dequereviter_type -
Modules/_collectionsmodule.c - tuplegetter_type -
Modules/_io/bufferedio.c - PyBufferedIOBase_Type -
-Modules/_io/bufferedio.c - PyBufferedRWPair_Type -
-Modules/_io/bufferedio.c - PyBufferedRandom_Type -
-Modules/_io/bufferedio.c - PyBufferedReader_Type -
-Modules/_io/bufferedio.c - PyBufferedWriter_Type -
-Modules/_io/bytesio.c - PyBytesIO_Type -
Modules/_io/bytesio.c - _PyBytesIOBuffer_Type -
-Modules/_io/fileio.c - PyFileIO_Type -
Modules/_io/iobase.c - PyIOBase_Type -
Modules/_io/iobase.c - PyRawIOBase_Type -
-Modules/_io/stringio.c - PyStringIO_Type -
Modules/_io/textio.c - PyIncrementalNewlineDecoder_Type -
Modules/_io/textio.c - PyTextIOBase_Type -
-Modules/_io/textio.c - PyTextIOWrapper_Type -
Modules/_io/winconsoleio.c - PyWindowsConsoleIO_Type -
Modules/_testcapi/vectorcall.c - MethodDescriptorBase_Type -
Modules/_testcapi/vectorcall.c - MethodDescriptorDerived_Type -