Skip to content

Commit 8d96a7a

Browse files
PyFileIO type
1 parent 4bd73bd commit 8d96a7a

File tree

6 files changed

+46
-66
lines changed

6 files changed

+46
-66
lines changed

Modules/_io/_iomodule.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,8 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode,
315315

316316
/* Create the Raw file stream */
317317
{
318-
PyObject *RawIO_class = (PyObject *)&PyFileIO_Type;
318+
_PyIO_State *state = get_io_state(module);
319+
PyObject *RawIO_class = (PyObject *)state->PyFileIO_Type;
319320
#ifdef MS_WINDOWS
320321
const PyConfig *config = _Py_GetConfig();
321322
if (!config->legacy_windows_stdio && _PyIO_get_console_type(path_or_fd) != '\0') {
@@ -646,7 +647,6 @@ static PyTypeObject* static_types[] = {
646647
&PyBufferedRandom_Type,
647648

648649
// PyRawIOBase_Type(PyIOBase_Type) subclasses
649-
&PyFileIO_Type,
650650
&_PyBytesIOBuffer_Type,
651651
#ifdef MS_WINDOWS
652652
&PyWindowsConsoleIO_Type,
@@ -706,7 +706,6 @@ PyInit__io(void)
706706
}
707707

708708
// Set type base classes
709-
PyFileIO_Type.tp_base = &PyRawIOBase_Type;
710709
PyBytesIO_Type.tp_base = &PyBufferedIOBase_Type;
711710
#ifdef MS_WINDOWS
712711
PyWindowsConsoleIO_Type.tp_base = &PyRawIOBase_Type;
@@ -724,6 +723,9 @@ PyInit__io(void)
724723
}
725724
}
726725

726+
// PyRawIOBase_Type(PyIOBase_Type) subclasses
727+
ADD_TYPE(m, state->PyFileIO_Type, &fileio_spec, &PyRawIOBase_Type);
728+
727729
// PyTextIOBase_Type(PyIOBase_Type) subclasses
728730
ADD_TYPE(m, state->PyStringIO_Type, &stringio_spec, &PyTextIOBase_Type);
729731
ADD_TYPE(m, state->PyTextIOWrapper_Type, &textiowrapper_spec,

Modules/_io/_iomodule.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ extern PyTypeObject PyBufferedIOBase_Type;
1414
extern PyTypeObject PyTextIOBase_Type;
1515

1616
/* Concrete classes */
17-
extern PyTypeObject PyFileIO_Type;
1817
extern PyTypeObject PyBytesIO_Type;
1918
extern PyTypeObject PyBufferedReader_Type;
2019
extern PyTypeObject PyBufferedWriter_Type;
@@ -23,6 +22,7 @@ extern PyTypeObject PyBufferedRandom_Type;
2322
extern PyTypeObject PyIncrementalNewlineDecoder_Type;
2423

2524
/* Type specs */
25+
extern PyType_Spec fileio_spec;
2626
extern PyType_Spec stringio_spec;
2727
extern PyType_Spec textiowrapper_spec;
2828

@@ -147,6 +147,7 @@ typedef struct {
147147
PyObject *unsupported_operation;
148148

149149
/* Types */
150+
PyTypeObject *PyFileIO_Type;
150151
PyTypeObject *PyStringIO_Type;
151152
PyTypeObject *PyTextIOWrapper_Type;
152153
} _PyIO_State;

Modules/_io/bufferedio.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1428,8 +1428,9 @@ _io_BufferedReader___init___impl(buffered *self, PyObject *raw,
14281428
return -1;
14291429
_bufferedreader_reset_buf(self);
14301430

1431+
_PyIO_State *state = IO_STATE();
14311432
self->fast_closed_checks = (Py_IS_TYPE(self, &PyBufferedReader_Type) &&
1432-
Py_IS_TYPE(raw, &PyFileIO_Type));
1433+
Py_IS_TYPE(raw, state->PyFileIO_Type));
14331434

14341435
self->ok = 1;
14351436
return 0;
@@ -1783,8 +1784,9 @@ _io_BufferedWriter___init___impl(buffered *self, PyObject *raw,
17831784
_bufferedwriter_reset_buf(self);
17841785
self->pos = 0;
17851786

1787+
_PyIO_State *state = IO_STATE();
17861788
self->fast_closed_checks = (Py_IS_TYPE(self, &PyBufferedWriter_Type) &&
1787-
Py_IS_TYPE(raw, &PyFileIO_Type));
1789+
Py_IS_TYPE(raw, state->PyFileIO_Type));
17881790

17891791
self->ok = 1;
17901792
return 0;
@@ -2295,8 +2297,9 @@ _io_BufferedRandom___init___impl(buffered *self, PyObject *raw,
22952297
_bufferedwriter_reset_buf(self);
22962298
self->pos = 0;
22972299

2300+
_PyIO_State *state = IO_STATE();
22982301
self->fast_closed_checks = (Py_IS_TYPE(self, &PyBufferedRandom_Type) &&
2299-
Py_IS_TYPE(raw, &PyFileIO_Type));
2302+
Py_IS_TYPE(raw, state->PyFileIO_Type));
23002303

23012304
self->ok = 1;
23022305
return 0;

Modules/_io/fileio.c

Lines changed: 30 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151

5252
/*[clinic input]
5353
module _io
54-
class _io.FileIO "fileio *" "&PyFileIO_Type"
54+
class _io.FileIO "fileio *" "clinic_state()->PyFileIO_Type"
5555
[clinic start generated code]*/
5656
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=1c77708b41fda70c]*/
5757

@@ -70,9 +70,7 @@ typedef struct {
7070
PyObject *dict;
7171
} fileio;
7272

73-
PyTypeObject PyFileIO_Type;
74-
75-
#define PyFileIO_Check(op) (PyObject_TypeCheck((op), &PyFileIO_Type))
73+
#define PyFileIO_Check(state, op) (PyObject_TypeCheck((op), state->PyFileIO_Type))
7674

7775
/* Forward declarations */
7876
static PyObject* portable_lseek(fileio *self, PyObject *posobj, int whence, bool suppress_pipe_error);
@@ -242,7 +240,8 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode,
242240
int fstat_result;
243241
int async_err = 0;
244242

245-
assert(PyFileIO_Check(self));
243+
_PyIO_State *state = IO_STATE();
244+
assert(PyFileIO_Check(state, self));
246245
if (self->fd >= 0) {
247246
if (self->closefd) {
248247
/* Have to close the existing file first. */
@@ -503,6 +502,7 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode,
503502
static int
504503
fileio_traverse(fileio *self, visitproc visit, void *arg)
505504
{
505+
Py_VISIT(Py_TYPE(self));
506506
Py_VISIT(self->dict);
507507
return 0;
508508
}
@@ -517,14 +517,16 @@ fileio_clear(fileio *self)
517517
static void
518518
fileio_dealloc(fileio *self)
519519
{
520+
PyTypeObject *tp = Py_TYPE(self);
520521
self->finalizing = 1;
521522
if (_PyIOBase_finalize((PyObject *) self) < 0)
522523
return;
523524
_PyObject_GC_UNTRACK(self);
524525
if (self->weakreflist != NULL)
525526
PyObject_ClearWeakRefs((PyObject *) self);
526527
Py_CLEAR(self->dict);
527-
Py_TYPE(self)->tp_free((PyObject *)self);
528+
tp->tp_free((PyObject *)self);
529+
Py_DECREF(tp);
528530
}
529531

530532
static PyObject *
@@ -1177,57 +1179,29 @@ static PyGetSetDef fileio_getsetlist[] = {
11771179
static PyMemberDef fileio_members[] = {
11781180
{"_blksize", T_UINT, offsetof(fileio, blksize), 0},
11791181
{"_finalizing", T_BOOL, offsetof(fileio, finalizing), 0},
1182+
{"__weaklistoffset__", T_PYSSIZET, offsetof(fileio, weakreflist), READONLY},
1183+
{"__dictoffset__", T_PYSSIZET, offsetof(fileio, dict), READONLY},
11801184
{NULL}
11811185
};
11821186

1183-
PyTypeObject PyFileIO_Type = {
1184-
PyVarObject_HEAD_INIT(NULL, 0)
1185-
"_io.FileIO",
1186-
sizeof(fileio),
1187-
0,
1188-
(destructor)fileio_dealloc, /* tp_dealloc */
1189-
0, /* tp_vectorcall_offset */
1190-
0, /* tp_getattr */
1191-
0, /* tp_setattr */
1192-
0, /* tp_as_async */
1193-
(reprfunc)fileio_repr, /* tp_repr */
1194-
0, /* tp_as_number */
1195-
0, /* tp_as_sequence */
1196-
0, /* tp_as_mapping */
1197-
0, /* tp_hash */
1198-
0, /* tp_call */
1199-
0, /* tp_str */
1200-
PyObject_GenericGetAttr, /* tp_getattro */
1201-
0, /* tp_setattro */
1202-
0, /* tp_as_buffer */
1203-
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
1204-
| Py_TPFLAGS_HAVE_GC, /* tp_flags */
1205-
_io_FileIO___init____doc__, /* tp_doc */
1206-
(traverseproc)fileio_traverse, /* tp_traverse */
1207-
(inquiry)fileio_clear, /* tp_clear */
1208-
0, /* tp_richcompare */
1209-
offsetof(fileio, weakreflist), /* tp_weaklistoffset */
1210-
0, /* tp_iter */
1211-
0, /* tp_iternext */
1212-
fileio_methods, /* tp_methods */
1213-
fileio_members, /* tp_members */
1214-
fileio_getsetlist, /* tp_getset */
1215-
0, /* tp_base */
1216-
0, /* tp_dict */
1217-
0, /* tp_descr_get */
1218-
0, /* tp_descr_set */
1219-
offsetof(fileio, dict), /* tp_dictoffset */
1220-
_io_FileIO___init__, /* tp_init */
1221-
PyType_GenericAlloc, /* tp_alloc */
1222-
fileio_new, /* tp_new */
1223-
PyObject_GC_Del, /* tp_free */
1224-
0, /* tp_is_gc */
1225-
0, /* tp_bases */
1226-
0, /* tp_mro */
1227-
0, /* tp_cache */
1228-
0, /* tp_subclasses */
1229-
0, /* tp_weaklist */
1230-
0, /* tp_del */
1231-
0, /* tp_version_tag */
1232-
0, /* tp_finalize */
1187+
static PyType_Slot fileio_slots[] = {
1188+
{Py_tp_dealloc, fileio_dealloc},
1189+
{Py_tp_repr, fileio_repr},
1190+
{Py_tp_doc, (void *)_io_FileIO___init____doc__},
1191+
{Py_tp_traverse, fileio_traverse},
1192+
{Py_tp_clear, fileio_clear},
1193+
{Py_tp_methods, fileio_methods},
1194+
{Py_tp_members, fileio_members},
1195+
{Py_tp_getset, fileio_getsetlist},
1196+
{Py_tp_init, _io_FileIO___init__},
1197+
{Py_tp_new, fileio_new},
1198+
{0, NULL},
1199+
};
1200+
1201+
PyType_Spec fileio_spec = {
1202+
.name = "_io.FileIO",
1203+
.basicsize = sizeof(fileio),
1204+
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
1205+
Py_TPFLAGS_IMMUTABLETYPE),
1206+
.slots = fileio_slots,
12331207
};

Modules/_io/textio.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1177,6 +1177,7 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer,
11771177
/* Finished sorting out the codec details */
11781178
Py_CLEAR(codec_info);
11791179

1180+
_PyIO_State *state = IO_STATE();
11801181
if (Py_IS_TYPE(buffer, &PyBufferedReader_Type) ||
11811182
Py_IS_TYPE(buffer, &PyBufferedWriter_Type) ||
11821183
Py_IS_TYPE(buffer, &PyBufferedRandom_Type))
@@ -1185,7 +1186,7 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer,
11851186
goto error;
11861187
/* Cache the raw FileIO object to speed up 'closed' checks */
11871188
if (raw != NULL) {
1188-
if (Py_IS_TYPE(raw, &PyFileIO_Type))
1189+
if (Py_IS_TYPE(raw, state->PyFileIO_Type))
11891190
self->raw = raw;
11901191
else
11911192
Py_DECREF(raw);
@@ -1213,7 +1214,7 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer,
12131214
goto error;
12141215
}
12151216

1216-
self->state = IO_STATE();
1217+
self->state = state;
12171218
self->ok = 1;
12181219
return 0;
12191220

Tools/c-analyzer/cpython/globals-to-fix.tsv

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,6 @@ Modules/_io/bufferedio.c - PyBufferedReader_Type -
323323
Modules/_io/bufferedio.c - PyBufferedWriter_Type -
324324
Modules/_io/bytesio.c - PyBytesIO_Type -
325325
Modules/_io/bytesio.c - _PyBytesIOBuffer_Type -
326-
Modules/_io/fileio.c - PyFileIO_Type -
327326
Modules/_io/iobase.c - PyIOBase_Type -
328327
Modules/_io/iobase.c - PyRawIOBase_Type -
329328
Modules/_io/textio.c - PyIncrementalNewlineDecoder_Type -

0 commit comments

Comments
 (0)