gh-101819: Adapt _io types to heap types, batch 1 (GH-101949)

Adapt StringIO, TextIOWrapper, FileIO, Buffered*, and BytesIO types.

Automerge-Triggered-By: GH:erlend-aasland
This commit is contained in:
Erlend E. Aasland 2023-02-20 14:46:20 +01:00 committed by GitHub
parent 2713631041
commit c00faf7943
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 463 additions and 478 deletions

View file

@ -1042,6 +1042,95 @@ def close(self):
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
@ -4671,7 +4760,7 @@ def load_tests(loader, tests, pattern):
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

View file

@ -10,7 +10,6 @@
#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
@ -315,8 +314,9 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode,
}
/* 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') {
@ -390,12 +390,15 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode,
{
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);
@ -417,7 +420,7 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode,
}
/* wraps into a TextIOWrapper */
wrapper = PyObject_CallFunction((PyObject *)&PyTextIOWrapper_Type,
wrapper = PyObject_CallFunction((PyObject *)state->PyTextIOWrapper_Type,
"OsssO",
buffer,
encoding, errors, newline,
@ -558,14 +561,6 @@ PyNumber_AsOff_t(PyObject *item, PyObject *err)
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)
{
@ -587,6 +582,15 @@ iomodule_traverse(PyObject *mod, visitproc visit, void *arg) {
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;
}
@ -599,6 +603,15 @@ iomodule_clear(PyObject *mod) {
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;
}
@ -612,7 +625,9 @@ iomodule_free(PyObject *mod) {
* Module definition
*/
#define clinic_state() (get_io_state(module))
#include "clinic/_iomodule.c.h"
#undef clinic_state
static PyMethodDef module_methods[] = {
_IO_OPEN_METHODDEF
@ -644,23 +659,11 @@ static PyTypeObject* static_types[] = {
&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,
};
@ -673,6 +676,17 @@ _PyIO_Fini(void)
}
}
#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)
@ -705,17 +719,9 @@ 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++) {
@ -725,6 +731,25 @@ PyInit__io(void)
}
}
// 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;

View file

@ -4,6 +4,9 @@
#include "exports.h"
#include "pycore_moduleobject.h" // _PyModule_GetState()
#include "structmember.h"
/* ABCs */
extern PyTypeObject PyIOBase_Type;
extern PyTypeObject PyRawIOBase_Type;
@ -11,16 +14,18 @@ extern PyTypeObject PyBufferedIOBase_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 */
@ -140,11 +145,37 @@ typedef struct {
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

View file

@ -18,12 +18,12 @@
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.
@ -366,6 +366,7 @@ _enter_buffered_busy(buffered *self)
static void
buffered_dealloc(buffered *self)
{
PyTypeObject *tp = Py_TYPE(self);
self->finalizing = 1;
if (_PyIOBase_finalize((PyObject *) self) < 0)
return;
@ -383,7 +384,8 @@ buffered_dealloc(buffered *self)
self->lock = NULL;
}
Py_CLEAR(self->dict);
Py_TYPE(self)->tp_free((PyObject *)self);
tp->tp_free((PyObject *)self);
Py_DECREF(tp);
}
static PyObject *
@ -399,6 +401,7 @@ buffered_sizeof(buffered *self, PyObject *Py_UNUSED(ignored))
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;
@ -1328,9 +1331,11 @@ buffered_iternext(buffered *self)
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);
}
@ -1428,8 +1433,11 @@ _io_BufferedReader___init___impl(buffered *self, PyObject *raw,
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;
@ -1783,8 +1791,11 @@ _io_BufferedWriter___init___impl(buffered *self, PyObject *raw,
_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;
@ -2090,13 +2101,16 @@ _io_BufferedRWPair___init___impl(rwpair *self, PyObject *reader,
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;
@ -2108,6 +2122,7 @@ _io_BufferedRWPair___init___impl(rwpair *self, PyObject *reader,
static int
bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
{
Py_VISIT(Py_TYPE(self));
Py_VISIT(self->dict);
return 0;
}
@ -2124,13 +2139,15 @@ bufferedrwpair_clear(rwpair *self)
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 *
@ -2295,14 +2312,17 @@ _io_BufferedRandom___init___impl(buffered *self, PyObject *raw,
_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[] = {
@ -2394,6 +2414,8 @@ static PyMethodDef bufferedreader_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}
};
@ -2405,58 +2427,27 @@ static PyGetSetDef bufferedreader_getset[] = {
};
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 */
@ -2480,6 +2471,8 @@ static PyMethodDef bufferedwriter_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}
};
@ -2491,58 +2484,26 @@ static PyGetSetDef bufferedwriter_getset[] = {
};
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},
@ -2563,61 +2524,35 @@ static PyMethodDef bufferedrwpair_methods[] = {
{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,
};
@ -2651,6 +2586,8 @@ static PyMethodDef bufferedrandom_methods[] = {
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}
};
@ -2662,54 +2599,24 @@ static PyGetSetDef bufferedrandom_getset[] = {
};
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,
};

View file

@ -5,9 +5,9 @@
/*[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
@ -881,6 +881,7 @@ bytesio_setstate(bytesio *self, PyObject *state)
static void
bytesio_dealloc(bytesio *self)
{
PyTypeObject *tp = Py_TYPE(self);
_PyObject_GC_UNTRACK(self);
if (self->exports > 0) {
PyErr_SetString(PyExc_SystemError,
@ -891,7 +892,8 @@ bytesio_dealloc(bytesio *self)
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 *
@ -971,6 +973,7 @@ bytesio_sizeof(bytesio *self, void *unused)
static int
bytesio_traverse(bytesio *self, visitproc visit, void *arg)
{
Py_VISIT(Py_TYPE(self));
Py_VISIT(self->dict);
return 0;
}
@ -983,7 +986,9 @@ bytesio_clear(bytesio *self)
}
#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,
@ -1016,48 +1021,34 @@ static struct PyMethodDef bytesio_methods[] = {
{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().

View file

@ -601,7 +601,7 @@ static int
_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;
@ -714,4 +714,4 @@ skip_optional_pos:
exit:
return return_value;
}
/*[clinic end generated code: output=953f1577e96e8d86 input=a9049054013a1b77]*/
/*[clinic end generated code: output=8412b10c04259bb8 input=a9049054013a1b77]*/

View file

@ -51,9 +51,9 @@
/*[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
@ -70,9 +70,7 @@ typedef struct {
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);
@ -242,7 +240,10 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode,
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. */
@ -503,6 +504,7 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode,
static int
fileio_traverse(fileio *self, visitproc visit, void *arg)
{
Py_VISIT(Py_TYPE(self));
Py_VISIT(self->dict);
return 0;
}
@ -517,6 +519,7 @@ fileio_clear(fileio *self)
static void
fileio_dealloc(fileio *self)
{
PyTypeObject *tp = Py_TYPE(self);
self->finalizing = 1;
if (_PyIOBase_finalize((PyObject *) self) < 0)
return;
@ -524,7 +527,8 @@ fileio_dealloc(fileio *self)
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 *
@ -1177,57 +1181,29 @@ static PyGetSetDef fileio_getsetlist[] = {
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,
};

View file

@ -13,9 +13,9 @@
/*[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
@ -43,6 +43,7 @@ typedef struct {
PyObject *dict;
PyObject *weakreflist;
_PyIO_State *module_state;
} stringio;
static int _io_StringIO___init__(PyObject *self, PyObject *args, PyObject *kwargs);
@ -401,7 +402,7 @@ stringio_iternext(stringio *self)
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);
}
@ -581,6 +582,7 @@ _io_StringIO_close_impl(stringio *self)
static int
stringio_traverse(stringio *self, visitproc visit, void *arg)
{
Py_VISIT(Py_TYPE(self));
Py_VISIT(self->dict);
return 0;
}
@ -595,6 +597,7 @@ stringio_clear(stringio *self)
static void
stringio_dealloc(stringio *self)
{
PyTypeObject *tp = Py_TYPE(self);
_PyObject_GC_UNTRACK(self);
self->ok = 0;
if (self->buf) {
@ -606,9 +609,11 @@ stringio_dealloc(stringio *self)
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 *
@ -745,7 +750,7 @@ _io_StringIO___init___impl(stringio *self, PyObject *value,
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;
@ -963,7 +968,9 @@ stringio_newlines(stringio *self, void *context)
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
@ -997,44 +1004,30 @@ static PyGetSetDef stringio_getset[] = {
{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,
};

View file

@ -19,9 +19,9 @@
/*[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 */
@ -682,6 +682,8 @@ typedef struct
PyObject *weakreflist;
PyObject *dict;
_PyIO_State *state;
} textio;
static void
@ -1175,15 +1177,16 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer,
/* 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);
@ -1211,6 +1214,7 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer,
goto error;
}
self->state = state;
self->ok = 1;
return 0;
@ -1387,6 +1391,7 @@ textiowrapper_clear(textio *self)
static void
textiowrapper_dealloc(textio *self)
{
PyTypeObject *tp = Py_TYPE(self);
self->finalizing = 1;
if (_PyIOBase_finalize((PyObject *) self) < 0)
return;
@ -1395,12 +1400,14 @@ textiowrapper_dealloc(textio *self)
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);
@ -1424,7 +1431,7 @@ textiowrapper_closed_get(textio *self, void *context);
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 { \
@ -3053,7 +3060,7 @@ textiowrapper_iternext(textio *self)
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);
}
@ -3145,7 +3152,9 @@ textiowrapper_chunk_size_set(textio *self, PyObject *arg, void *context)
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
@ -3229,6 +3238,8 @@ static PyMemberDef textiowrapper_members[] = {
{"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}
};
@ -3244,54 +3255,24 @@ static PyGetSetDef textiowrapper_getset[] = {
{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,
};

View file

@ -317,19 +317,11 @@ Modules/_collectionsmodule.c - dequeiter_type -
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 -

Can't render this file because it has a wrong number of fields in line 4.