Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
StringIO type
  • Loading branch information
erlend-aasland committed Feb 15, 2023
commit bd19a20f18e048b368b6077de6964afe93564795
17 changes: 15 additions & 2 deletions Modules/_io/_iomodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,9 @@ iomodule_free(PyObject *mod) {
* Module definition
*/

#define clinic_state() (IO_STATE())
#include "clinic/_iomodule.c.h"
#undef clinic_state

static PyMethodDef module_methods[] = {
_IO_OPEN_METHODDEF
Expand Down Expand Up @@ -659,7 +661,6 @@ static PyTypeObject* static_types[] = {
#endif

// PyTextIOBase_Type(PyIOBase_Type) subclasses
&PyStringIO_Type,
&PyTextIOWrapper_Type,
};

Expand All @@ -673,6 +674,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)
Expand Down Expand Up @@ -707,7 +719,6 @@ 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
Expand All @@ -725,6 +736,8 @@ PyInit__io(void)
}
}

ADD_TYPE(m, state->PyStringIO_Type, &stringio_spec, &PyTextIOBase_Type);

state->initialized = 1;

return m;
Expand Down
9 changes: 8 additions & 1 deletion Modules/_io/_iomodule.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

#include "exports.h"

#include "structmember.h"

/* ABCs */
extern PyTypeObject PyIOBase_Type;
extern PyTypeObject PyRawIOBase_Type;
Expand All @@ -13,14 +15,16 @@ 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 stringio_spec;

#ifdef MS_WINDOWS
extern PyTypeObject PyWindowsConsoleIO_Type;
#endif /* MS_WINDOWS */
Expand Down Expand Up @@ -140,6 +144,9 @@ typedef struct {
PyObject *locale_module;

PyObject *unsupported_operation;

/* Types */
PyTypeObject *PyStringIO_Type;
} _PyIO_State;

#define IO_MOD_STATE(mod) ((_PyIO_State *)PyModule_GetState(mod))
Expand Down
83 changes: 38 additions & 45 deletions Modules/_io/stringio.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -401,7 +401,8 @@ stringio_iternext(stringio *self)
CHECK_CLOSED(self);
ENSURE_REALIZED(self);

if (Py_IS_TYPE(self, &PyStringIO_Type)) {
_PyIO_State *state = IO_STATE();
if (Py_IS_TYPE(self, state->PyStringIO_Type)) {
/* Skip method call overhead for speed */
line = _stringio_readline(self, -1);
}
Expand Down Expand Up @@ -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;
}
Expand All @@ -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) {
Expand All @@ -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 *
Expand Down Expand Up @@ -963,7 +968,9 @@ stringio_newlines(stringio *self, void *context)
return PyObject_GetAttr(self->decoder, &_Py_ID(newlines));
}

#define clinic_state() (IO_STATE())
#include "clinic/stringio.c.h"
#undef clinic_state

static struct PyMethodDef stringio_methods[] = {
_IO_STRINGIO_CLOSE_METHODDEF
Expand Down Expand Up @@ -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,
};
1 change: 0 additions & 1 deletion Tools/c-analyzer/cpython/globals-to-fix.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,6 @@ 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 -
Expand Down