Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit dfc1e9e

Browse filesBrowse files
gh-101819: Prepare to modernize the _io extension
* Add references to static types to _PyIO_State: * PyBufferedIOBase_Type * PyBytesIOBuffer_Type * PyIncrementalNewlineDecoder_Type * PyRawIOBase_Type * PyTextIOBase_Type * Add the defining class to methods: * _io.BytesIO.getbuffer() * _io.FileIO.close() * Add get_io_state_by_cls() function. * Add state parameter to _textiowrapper_decode() * _io_TextIOWrapper___init__() now sets self->state before calling _textiowrapper_set_decoder(). Co-Authored-by: Erlend E. Aasland <erlend.aasland@protonmail.com>
1 parent 81fc135 commit dfc1e9e
Copy full SHA for dfc1e9e

File tree

9 files changed

+92
-37
lines changed
Filter options

9 files changed

+92
-37
lines changed

‎Modules/_io/_iomodule.c

Copy file name to clipboardExpand all lines: Modules/_io/_iomodule.c
+27-8Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -583,13 +583,18 @@ iomodule_traverse(PyObject *mod, visitproc visit, void *arg) {
583583
Py_VISIT(state->locale_module);
584584
Py_VISIT(state->unsupported_operation);
585585

586+
Py_VISIT(state->PyIncrementalNewlineDecoder_Type);
587+
Py_VISIT(state->PyRawIOBase_Type);
588+
Py_VISIT(state->PyBufferedIOBase_Type);
586589
Py_VISIT(state->PyBufferedRWPair_Type);
587590
Py_VISIT(state->PyBufferedRandom_Type);
588591
Py_VISIT(state->PyBufferedReader_Type);
589592
Py_VISIT(state->PyBufferedWriter_Type);
593+
Py_VISIT(state->PyBytesIOBuffer_Type);
590594
Py_VISIT(state->PyBytesIO_Type);
591595
Py_VISIT(state->PyFileIO_Type);
592596
Py_VISIT(state->PyStringIO_Type);
597+
Py_VISIT(state->PyTextIOBase_Type);
593598
Py_VISIT(state->PyTextIOWrapper_Type);
594599
return 0;
595600
}
@@ -604,13 +609,18 @@ iomodule_clear(PyObject *mod) {
604609
Py_CLEAR(state->locale_module);
605610
Py_CLEAR(state->unsupported_operation);
606611

612+
Py_CLEAR(state->PyIncrementalNewlineDecoder_Type);
613+
Py_CLEAR(state->PyRawIOBase_Type);
614+
Py_CLEAR(state->PyBufferedIOBase_Type);
607615
Py_CLEAR(state->PyBufferedRWPair_Type);
608616
Py_CLEAR(state->PyBufferedRandom_Type);
609617
Py_CLEAR(state->PyBufferedReader_Type);
610618
Py_CLEAR(state->PyBufferedWriter_Type);
619+
Py_CLEAR(state->PyBytesIOBuffer_Type);
611620
Py_CLEAR(state->PyBytesIO_Type);
612621
Py_CLEAR(state->PyFileIO_Type);
613622
Py_CLEAR(state->PyStringIO_Type);
623+
Py_CLEAR(state->PyTextIOBase_Type);
614624
Py_CLEAR(state->PyTextIOWrapper_Type);
615625
return 0;
616626
}
@@ -749,24 +759,33 @@ PyInit__io(void)
749759
}
750760
}
751761

762+
// Base classes
763+
state->PyIncrementalNewlineDecoder_Type = (PyTypeObject *)Py_NewRef(&PyIncrementalNewlineDecoder_Type);
764+
765+
// PyIOBase_Type subclasses
766+
state->PyRawIOBase_Type = (PyTypeObject *)Py_NewRef(&PyRawIOBase_Type);
767+
state->PyBufferedIOBase_Type = (PyTypeObject *)Py_NewRef(&PyBufferedIOBase_Type);
768+
state->PyTextIOBase_Type = (PyTypeObject *)Py_NewRef(&PyTextIOBase_Type);
769+
752770
// PyBufferedIOBase_Type(PyIOBase_Type) subclasses
753-
ADD_TYPE(m, state->PyBytesIO_Type, &bytesio_spec, &PyBufferedIOBase_Type);
771+
ADD_TYPE(m, state->PyBytesIO_Type, &bytesio_spec, state->PyBufferedIOBase_Type);
754772
ADD_TYPE(m, state->PyBufferedWriter_Type, &bufferedwriter_spec,
755-
&PyBufferedIOBase_Type);
773+
state->PyBufferedIOBase_Type);
756774
ADD_TYPE(m, state->PyBufferedReader_Type, &bufferedreader_spec,
757-
&PyBufferedIOBase_Type);
775+
state->PyBufferedIOBase_Type);
758776
ADD_TYPE(m, state->PyBufferedRWPair_Type, &bufferedrwpair_spec,
759-
&PyBufferedIOBase_Type);
777+
state->PyBufferedIOBase_Type);
760778
ADD_TYPE(m, state->PyBufferedRandom_Type, &bufferedrandom_spec,
761-
&PyBufferedIOBase_Type);
779+
state->PyBufferedIOBase_Type);
762780

763781
// PyRawIOBase_Type(PyIOBase_Type) subclasses
764-
ADD_TYPE(m, state->PyFileIO_Type, &fileio_spec, &PyRawIOBase_Type);
782+
state->PyBytesIOBuffer_Type = (PyTypeObject *)Py_NewRef(&_PyBytesIOBuffer_Type);
783+
ADD_TYPE(m, state->PyFileIO_Type, &fileio_spec, state->PyRawIOBase_Type);
765784

766785
// PyTextIOBase_Type(PyIOBase_Type) subclasses
767-
ADD_TYPE(m, state->PyStringIO_Type, &stringio_spec, &PyTextIOBase_Type);
786+
ADD_TYPE(m, state->PyStringIO_Type, &stringio_spec, state->PyTextIOBase_Type);
768787
ADD_TYPE(m, state->PyTextIOWrapper_Type, &textiowrapper_spec,
769-
&PyTextIOBase_Type);
788+
state->PyTextIOBase_Type);
770789

771790
state->initialized = 1;
772791

‎Modules/_io/_iomodule.h

Copy file name to clipboardExpand all lines: Modules/_io/_iomodule.h
+14Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "exports.h"
66

77
#include "pycore_moduleobject.h" // _PyModule_GetState()
8+
#include "pycore_typeobject.h" // _PyType_GetModuleState()
89
#include "structmember.h"
910

1011
/* ABCs */
@@ -147,13 +148,18 @@ typedef struct {
147148
PyObject *unsupported_operation;
148149

149150
/* Types */
151+
PyTypeObject *PyIncrementalNewlineDecoder_Type;
152+
PyTypeObject *PyRawIOBase_Type;
153+
PyTypeObject *PyBufferedIOBase_Type;
150154
PyTypeObject *PyBufferedRWPair_Type;
151155
PyTypeObject *PyBufferedRandom_Type;
152156
PyTypeObject *PyBufferedReader_Type;
153157
PyTypeObject *PyBufferedWriter_Type;
158+
PyTypeObject *PyBytesIOBuffer_Type;
154159
PyTypeObject *PyBytesIO_Type;
155160
PyTypeObject *PyFileIO_Type;
156161
PyTypeObject *PyStringIO_Type;
162+
PyTypeObject *PyTextIOBase_Type;
157163
PyTypeObject *PyTextIOWrapper_Type;
158164
} _PyIO_State;
159165

@@ -168,6 +174,14 @@ get_io_state(PyObject *module)
168174
return (_PyIO_State *)state;
169175
}
170176

177+
static inline _PyIO_State *
178+
get_io_state_by_cls(PyTypeObject *cls)
179+
{
180+
void *state = _PyType_GetModuleState(cls);
181+
assert(state != NULL);
182+
return (_PyIO_State *)state;
183+
}
184+
171185
static inline _PyIO_State *
172186
find_io_state_by_def(PyTypeObject *type)
173187
{

‎Modules/_io/bufferedio.c

Copy file name to clipboardExpand all lines: Modules/_io/bufferedio.c
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2231,7 +2231,7 @@ bufferedrwpair_close(rwpair *self, PyObject *Py_UNUSED(ignored))
22312231
}
22322232
else {
22332233
Py_DECREF(ret);
2234-
}
2234+
}
22352235
ret = _forward_call(self->reader, &_Py_ID(close), NULL);
22362236
if (exc != NULL) {
22372237
_PyErr_ChainExceptions1(exc);

‎Modules/_io/bytesio.c

Copy file name to clipboardExpand all lines: Modules/_io/bytesio.c
+7-3Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -308,14 +308,18 @@ _io_BytesIO_flush_impl(bytesio *self)
308308
/*[clinic input]
309309
_io.BytesIO.getbuffer
310310
311+
cls: defining_class
312+
/
313+
311314
Get a read-write view over the contents of the BytesIO object.
312315
[clinic start generated code]*/
313316

314317
static PyObject *
315-
_io_BytesIO_getbuffer_impl(bytesio *self)
316-
/*[clinic end generated code: output=72cd7c6e13aa09ed input=8f738ef615865176]*/
318+
_io_BytesIO_getbuffer_impl(bytesio *self, PyTypeObject *cls)
319+
/*[clinic end generated code: output=045091d7ce87fe4e input=0668fbb48f95dffa]*/
317320
{
318-
PyTypeObject *type = &_PyBytesIOBuffer_Type;
321+
_PyIO_State *state = get_io_state_by_cls(cls);
322+
PyTypeObject *type = state->PyBytesIOBuffer_Type;
319323
bytesiobuf *buf;
320324
PyObject *view;
321325

‎Modules/_io/clinic/bytesio.c.h

Copy file name to clipboardExpand all lines: Modules/_io/clinic/bytesio.c.h
+9-5Lines changed: 9 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Modules/_io/clinic/fileio.c.h

Copy file name to clipboardExpand all lines: Modules/_io/clinic/fileio.c.h
+9-5Lines changed: 9 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Modules/_io/fileio.c

Copy file name to clipboardExpand all lines: Modules/_io/fileio.c
+9-4Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,25 +130,30 @@ internal_close(fileio *self)
130130
/*[clinic input]
131131
_io.FileIO.close
132132
133+
cls: defining_class
134+
/
135+
133136
Close the file.
134137
135138
A closed file cannot be used for further I/O operations. close() may be
136139
called more than once without error.
137140
[clinic start generated code]*/
138141

139142
static PyObject *
140-
_io_FileIO_close_impl(fileio *self)
141-
/*[clinic end generated code: output=7737a319ef3bad0b input=f35231760d54a522]*/
143+
_io_FileIO_close_impl(fileio *self, PyTypeObject *cls)
144+
/*[clinic end generated code: output=c30cbe9d1f23ca58 input=70da49e63db7c64d]*/
142145
{
143146
PyObject *res;
144-
PyObject *exc;
145147
int rc;
146-
res = PyObject_CallMethodOneArg((PyObject*)&PyRawIOBase_Type,
148+
_PyIO_State *state = get_io_state_by_cls(cls);
149+
res = PyObject_CallMethodOneArg((PyObject*)state->PyRawIOBase_Type,
147150
&_Py_ID(close), (PyObject *)self);
148151
if (!self->closefd) {
149152
self->fd = -1;
150153
return res;
151154
}
155+
156+
PyObject *exc;
152157
if (res == NULL) {
153158
exc = PyErr_GetRaisedException();
154159
}

‎Modules/_io/stringio.c

Copy file name to clipboardExpand all lines: Modules/_io/stringio.c
+3-2Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -716,9 +716,10 @@ _io_StringIO___init___impl(stringio *self, PyObject *value,
716716
self->writenl = Py_NewRef(self->readnl);
717717
}
718718

719+
_PyIO_State *module_state = find_io_state_by_def(Py_TYPE(self));
719720
if (self->readuniversal) {
720721
self->decoder = PyObject_CallFunctionObjArgs(
721-
(PyObject *)&PyIncrementalNewlineDecoder_Type,
722+
(PyObject *)module_state->PyIncrementalNewlineDecoder_Type,
722723
Py_None, self->readtranslate ? Py_True : Py_False, NULL);
723724
if (self->decoder == NULL)
724725
return -1;
@@ -750,7 +751,7 @@ _io_StringIO___init___impl(stringio *self, PyObject *value,
750751
self->state = STATE_ACCUMULATING;
751752
}
752753
self->pos = 0;
753-
self->module_state = find_io_state_by_def(Py_TYPE(self));
754+
self->module_state = module_state;
754755
self->closed = 0;
755756
self->ok = 1;
756757
return 0;

‎Modules/_io/textio.c

Copy file name to clipboardExpand all lines: Modules/_io/textio.c
+13-9Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@
1818

1919
/*[clinic input]
2020
module _io
21-
class _io.IncrementalNewlineDecoder "nldecoder_object *" "&PyIncrementalNewlineDecoder_Type"
21+
class _io.IncrementalNewlineDecoder "nldecoder_object *" "clinic_state()->PyIncrementalNewlineDecoder_Type"
2222
class _io.TextIOWrapper "textio *" "clinic_state()->TextIOWrapper_Type"
2323
[clinic start generated code]*/
24-
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=d3f032e90f74c8f2]*/
24+
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=81f67cf54eaa6001]*/
2525

2626
/* TextIOBase */
2727

@@ -872,8 +872,9 @@ _textiowrapper_set_decoder(textio *self, PyObject *codec_info,
872872
return -1;
873873

874874
if (self->readuniversal) {
875+
_PyIO_State *state = self->state;
875876
PyObject *incrementalDecoder = PyObject_CallFunctionObjArgs(
876-
(PyObject *)&PyIncrementalNewlineDecoder_Type,
877+
(PyObject *)state->PyIncrementalNewlineDecoder_Type,
877878
self->decoder, self->readtranslate ? Py_True : Py_False, NULL);
878879
if (incrementalDecoder == NULL)
879880
return -1;
@@ -884,11 +885,12 @@ _textiowrapper_set_decoder(textio *self, PyObject *codec_info,
884885
}
885886

886887
static PyObject*
887-
_textiowrapper_decode(PyObject *decoder, PyObject *bytes, int eof)
888+
_textiowrapper_decode(_PyIO_State *state, PyObject *decoder, PyObject *bytes,
889+
int eof)
888890
{
889891
PyObject *chars;
890892

891-
if (Py_IS_TYPE(decoder, &PyIncrementalNewlineDecoder_Type))
893+
if (Py_IS_TYPE(decoder, state->PyIncrementalNewlineDecoder_Type))
892894
chars = _PyIncrementalNewlineDecoder_decode(decoder, bytes, eof);
893895
else
894896
chars = PyObject_CallMethodObjArgs(decoder, &_Py_ID(decode), bytes,
@@ -1167,6 +1169,8 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer,
11671169
self->buffer = Py_NewRef(buffer);
11681170

11691171
/* Build the decoder object */
1172+
_PyIO_State *state = find_io_state_by_def(Py_TYPE(self));
1173+
self->state = state;
11701174
if (_textiowrapper_set_decoder(self, codec_info, PyUnicode_AsUTF8(errors)) != 0)
11711175
goto error;
11721176

@@ -1177,7 +1181,6 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer,
11771181
/* Finished sorting out the codec details */
11781182
Py_CLEAR(codec_info);
11791183

1180-
_PyIO_State *state = find_io_state_by_def(Py_TYPE(self));
11811184
if (Py_IS_TYPE(buffer, state->PyBufferedReader_Type) ||
11821185
Py_IS_TYPE(buffer, state->PyBufferedWriter_Type) ||
11831186
Py_IS_TYPE(buffer, state->PyBufferedRandom_Type))
@@ -1214,7 +1217,6 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer,
12141217
goto error;
12151218
}
12161219

1217-
self->state = state;
12181220
self->ok = 1;
12191221
return 0;
12201222

@@ -1843,7 +1845,8 @@ textiowrapper_read_chunk(textio *self, Py_ssize_t size_hint)
18431845
nbytes = input_chunk_buf.len;
18441846
eof = (nbytes == 0);
18451847

1846-
decoded_chars = _textiowrapper_decode(self->decoder, input_chunk, eof);
1848+
decoded_chars = _textiowrapper_decode(self->state, self->decoder,
1849+
input_chunk, eof);
18471850
PyBuffer_Release(&input_chunk_buf);
18481851
if (decoded_chars == NULL)
18491852
goto fail;
@@ -1913,7 +1916,8 @@ _io_TextIOWrapper_read_impl(textio *self, Py_ssize_t n)
19131916
if (bytes == NULL)
19141917
goto fail;
19151918

1916-
if (Py_IS_TYPE(self->decoder, &PyIncrementalNewlineDecoder_Type))
1919+
_PyIO_State *state = self->state;
1920+
if (Py_IS_TYPE(self->decoder, state->PyIncrementalNewlineDecoder_Type))
19171921
decoded = _PyIncrementalNewlineDecoder_decode(self->decoder,
19181922
bytes, 1);
19191923
else

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.