From 14f923e938d89053653d3722770d81f8a5c814db Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 9 May 2023 18:04:11 +0200 Subject: [PATCH 01/12] Refactor: replace query with parameter Pass module state to bufferediobase_unsupported() --- Modules/_io/bufferedio.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index 723d16b47fef9f..3c6f98f345fd01 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -106,11 +106,9 @@ _io__BufferedIOBase_readinto1_impl(PyObject *self, Py_buffer *buffer) } static PyObject * -bufferediobase_unsupported(const char *message) +bufferediobase_unsupported(_PyIO_State *state, const char *message) { - _PyIO_State *state = IO_STATE(); - if (state != NULL) - PyErr_SetString(state->unsupported_operation, message); + PyErr_SetString(state->unsupported_operation, message); return NULL; } @@ -127,7 +125,8 @@ static PyObject * _io__BufferedIOBase_detach_impl(PyObject *self) /*[clinic end generated code: output=754977c8d10ed88c input=822427fb58fe4169]*/ { - return bufferediobase_unsupported("detach"); + _PyIO_State *state = IO_STATE(); + return bufferediobase_unsupported(state, "detach"); } PyDoc_STRVAR(bufferediobase_read_doc, @@ -151,7 +150,8 @@ PyDoc_STRVAR(bufferediobase_read_doc, static PyObject * bufferediobase_read(PyObject *self, PyObject *args) { - return bufferediobase_unsupported("read"); + _PyIO_State *state = IO_STATE(); + return bufferediobase_unsupported(state, "read"); } PyDoc_STRVAR(bufferediobase_read1_doc, @@ -164,7 +164,8 @@ PyDoc_STRVAR(bufferediobase_read1_doc, static PyObject * bufferediobase_read1(PyObject *self, PyObject *args) { - return bufferediobase_unsupported("read1"); + _PyIO_State *state = IO_STATE(); + return bufferediobase_unsupported(state, "read1"); } PyDoc_STRVAR(bufferediobase_write_doc, @@ -179,7 +180,8 @@ PyDoc_STRVAR(bufferediobase_write_doc, static PyObject * bufferediobase_write(PyObject *self, PyObject *args) { - return bufferediobase_unsupported("write"); + _PyIO_State *state = IO_STATE(); + return bufferediobase_unsupported(state, "write"); } @@ -1298,7 +1300,8 @@ _io__Buffered_truncate_impl(buffered *self, PyObject *pos) CHECK_INITIALIZED(self) CHECK_CLOSED(self, "truncate of closed file") if (!self->writable) { - return bufferediobase_unsupported("truncate"); + _PyIO_State *state = IO_STATE(); + return bufferediobase_unsupported(state, "truncate"); } if (!ENTER_BUFFERED(self)) return NULL; From 482f13404ff6a7d1e1b3c4f158de641939bf0b7c Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 9 May 2023 18:04:51 +0200 Subject: [PATCH 02/12] Refactor: replace query with parameter Pass module state to iobase_unsupported() --- Modules/_io/iobase.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c index 682ed000eb1fd9..b08e679fb2a219 100644 --- a/Modules/_io/iobase.c +++ b/Modules/_io/iobase.c @@ -71,11 +71,9 @@ PyDoc_STRVAR(iobase_doc, /* Internal methods */ static PyObject * -iobase_unsupported(const char *message) +iobase_unsupported(_PyIO_State *state, const char *message) { - _PyIO_State *state = IO_STATE(); - if (state != NULL) - PyErr_SetString(state->unsupported_operation, message); + PyErr_SetString(state->unsupported_operation, message); return NULL; } @@ -97,7 +95,8 @@ PyDoc_STRVAR(iobase_seek_doc, static PyObject * iobase_seek(PyObject *self, PyObject *args) { - return iobase_unsupported("seek"); + _PyIO_State *state = IO_STATE(); + return iobase_unsupported(state, "seek"); } /*[clinic input] @@ -122,7 +121,8 @@ PyDoc_STRVAR(iobase_truncate_doc, static PyObject * iobase_truncate(PyObject *self, PyObject *args) { - return iobase_unsupported("truncate"); + _PyIO_State *state = IO_STATE(); + return iobase_unsupported(state, "truncate"); } static int @@ -379,7 +379,8 @@ _PyIOBase_check_seekable(PyObject *self, PyObject *args) return NULL; if (res != Py_True) { Py_CLEAR(res); - iobase_unsupported("File or stream is not seekable."); + _PyIO_State *state = IO_STATE(); + iobase_unsupported(state, "File or stream is not seekable."); return NULL; } if (args == Py_True) { @@ -412,7 +413,8 @@ _PyIOBase_check_readable(PyObject *self, PyObject *args) return NULL; if (res != Py_True) { Py_CLEAR(res); - iobase_unsupported("File or stream is not readable."); + _PyIO_State *state = IO_STATE(); + iobase_unsupported(state, "File or stream is not readable."); return NULL; } if (args == Py_True) { @@ -445,7 +447,8 @@ _PyIOBase_check_writable(PyObject *self, PyObject *args) return NULL; if (res != Py_True) { Py_CLEAR(res); - iobase_unsupported("File or stream is not writable."); + _PyIO_State *state = IO_STATE(); + iobase_unsupported(state, "File or stream is not writable."); return NULL; } if (args == Py_True) { @@ -487,7 +490,8 @@ static PyObject * _io__IOBase_fileno_impl(PyObject *self) /*[clinic end generated code: output=7cc0973f0f5f3b73 input=4e37028947dc1cc8]*/ { - return iobase_unsupported("fileno"); + _PyIO_State *state = IO_STATE(); + return iobase_unsupported(state, "fileno"); } /*[clinic input] From 8adc0cd0e7eb3b295f7455eeedb6fc31b2c9d391 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 9 May 2023 18:20:50 +0200 Subject: [PATCH 03/12] Refactor: hide delegate Add method wrapper for _PyIOBase_check_seekable. --- Modules/_io/iobase.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c index b08e679fb2a219..423aa5a6a5d051 100644 --- a/Modules/_io/iobase.c +++ b/Modules/_io/iobase.c @@ -204,6 +204,12 @@ _PyIOBase_check_closed(PyObject *self, PyObject *args) Py_RETURN_NONE; } +static PyObject * +iobase_check_seekable(PyObject *self, PyObject *args) +{ + return _PyIOBase_check_seekable(self, args); +} + /* XXX: IOBase thinks it has to maintain its own internal state in `__IOBase_closed` and call flush() by itself, but it is redundant with whatever behaviour a non-trivial derived class will implement. */ @@ -802,7 +808,7 @@ static PyMethodDef iobase_methods[] = { _IO__IOBASE_WRITABLE_METHODDEF {"_checkClosed", _PyIOBase_check_closed, METH_NOARGS}, - {"_checkSeekable", _PyIOBase_check_seekable, METH_NOARGS}, + {"_checkSeekable", iobase_check_seekable, METH_NOARGS}, {"_checkReadable", _PyIOBase_check_readable, METH_NOARGS}, {"_checkWritable", _PyIOBase_check_writable, METH_NOARGS}, From 703440a7e1717d518ac5b848e6fe72dc002d8bf1 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 9 May 2023 18:22:47 +0200 Subject: [PATCH 04/12] Refactor: hide delegate Add method wraper for _PyIOBase_check_readable --- Modules/_io/iobase.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c index 423aa5a6a5d051..f8f58577a964d8 100644 --- a/Modules/_io/iobase.c +++ b/Modules/_io/iobase.c @@ -210,6 +210,12 @@ iobase_check_seekable(PyObject *self, PyObject *args) return _PyIOBase_check_seekable(self, args); } +static PyObject * +iobase_check_readable(PyObject *self, PyObject *args) +{ + return _PyIOBase_check_readable(self, args); +} + /* XXX: IOBase thinks it has to maintain its own internal state in `__IOBase_closed` and call flush() by itself, but it is redundant with whatever behaviour a non-trivial derived class will implement. */ @@ -809,7 +815,7 @@ static PyMethodDef iobase_methods[] = { {"_checkClosed", _PyIOBase_check_closed, METH_NOARGS}, {"_checkSeekable", iobase_check_seekable, METH_NOARGS}, - {"_checkReadable", _PyIOBase_check_readable, METH_NOARGS}, + {"_checkReadable", iobase_check_readable, METH_NOARGS}, {"_checkWritable", _PyIOBase_check_writable, METH_NOARGS}, _IO__IOBASE_FILENO_METHODDEF From ea9c0989813665aae0cf757f56dc8b985aa9bdef Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 9 May 2023 18:24:21 +0200 Subject: [PATCH 05/12] Refactor: hide delegate Add method wraper for _PyIOBase_check_writable --- Modules/_io/iobase.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c index f8f58577a964d8..90537c00c11133 100644 --- a/Modules/_io/iobase.c +++ b/Modules/_io/iobase.c @@ -216,6 +216,12 @@ iobase_check_readable(PyObject *self, PyObject *args) return _PyIOBase_check_readable(self, args); } +static PyObject * +iobase_check_writable(PyObject *self, PyObject *args) +{ + return _PyIOBase_check_writable(self, args); +} + /* XXX: IOBase thinks it has to maintain its own internal state in `__IOBase_closed` and call flush() by itself, but it is redundant with whatever behaviour a non-trivial derived class will implement. */ @@ -816,7 +822,7 @@ static PyMethodDef iobase_methods[] = { {"_checkClosed", _PyIOBase_check_closed, METH_NOARGS}, {"_checkSeekable", iobase_check_seekable, METH_NOARGS}, {"_checkReadable", iobase_check_readable, METH_NOARGS}, - {"_checkWritable", _PyIOBase_check_writable, METH_NOARGS}, + {"_checkWritable", iobase_check_writable, METH_NOARGS}, _IO__IOBASE_FILENO_METHODDEF _IO__IOBASE_ISATTY_METHODDEF From e940ed3631cc57df552bb2b8454ae2817b3c114b Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 9 May 2023 18:33:04 +0200 Subject: [PATCH 06/12] Add io state struct forward declaration. --- Modules/_io/_iomodule.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Modules/_io/_iomodule.h b/Modules/_io/_iomodule.h index 1bf301c9cf0a94..157055f9006d42 100644 --- a/Modules/_io/_iomodule.h +++ b/Modules/_io/_iomodule.h @@ -34,6 +34,7 @@ extern PyType_Spec winconsoleio_spec; * with args=NULL, and return a new reference. * BUT when args=Py_True is passed, they return a borrowed reference. */ +struct _io_state; // Forward decl. extern PyObject* _PyIOBase_check_readable(PyObject *self, PyObject *args); extern PyObject* _PyIOBase_check_writable(PyObject *self, PyObject *args); extern PyObject* _PyIOBase_check_seekable(PyObject *self, PyObject *args); @@ -140,7 +141,7 @@ extern Py_off_t PyNumber_AsOff_t(PyObject *item, PyObject *err); extern PyModuleDef _PyIO_Module; -typedef struct { +typedef struct _io_state { int initialized; PyObject *unsupported_operation; From c68d657173994b1b3d7be543ae6bd789838f313f Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 9 May 2023 18:31:31 +0200 Subject: [PATCH 07/12] Refactor: replace query with parameter Pass module state to _PyIOBase_check_seekable() --- Modules/_io/_iomodule.h | 3 ++- Modules/_io/bufferedio.c | 9 ++++++--- Modules/_io/iobase.c | 6 +++--- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Modules/_io/_iomodule.h b/Modules/_io/_iomodule.h index 157055f9006d42..603f2caf31dff0 100644 --- a/Modules/_io/_iomodule.h +++ b/Modules/_io/_iomodule.h @@ -37,7 +37,8 @@ extern PyType_Spec winconsoleio_spec; struct _io_state; // Forward decl. extern PyObject* _PyIOBase_check_readable(PyObject *self, PyObject *args); extern PyObject* _PyIOBase_check_writable(PyObject *self, PyObject *args); -extern PyObject* _PyIOBase_check_seekable(PyObject *self, PyObject *args); +extern PyObject* _PyIOBase_check_seekable(struct _io_state *state, + PyObject *self, PyObject *args); extern PyObject* _PyIOBase_check_closed(PyObject *self, PyObject *args); /* Helper for finalization. diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index 3c6f98f345fd01..be875e017bf29e 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -1224,8 +1224,10 @@ _io__Buffered_seek_impl(buffered *self, PyObject *targetobj, int whence) CHECK_CLOSED(self, "seek of closed file") - if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL) + _PyIO_State *state = IO_STATE(); + if (_PyIOBase_check_seekable(state, self->raw, Py_True) == NULL) { return NULL; + } target = PyNumber_AsOff_t(targetobj, PyExc_ValueError); if (target == -1 && PyErr_Occurred()) @@ -2293,8 +2295,10 @@ _io_BufferedRandom___init___impl(buffered *self, PyObject *raw, self->ok = 0; self->detached = 0; - if (_PyIOBase_check_seekable(raw, Py_True) == NULL) + _PyIO_State *state = find_io_state_by_def(Py_TYPE(self)); + if (_PyIOBase_check_seekable(state, raw, Py_True) == NULL) { return -1; + } if (_PyIOBase_check_readable(raw, Py_True) == NULL) return -1; if (_PyIOBase_check_writable(raw, Py_True) == NULL) @@ -2312,7 +2316,6 @@ _io_BufferedRandom___init___impl(buffered *self, PyObject *raw, _bufferedwriter_reset_buf(self); self->pos = 0; - _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)); diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c index 90537c00c11133..7898fae6c35ec4 100644 --- a/Modules/_io/iobase.c +++ b/Modules/_io/iobase.c @@ -207,7 +207,8 @@ _PyIOBase_check_closed(PyObject *self, PyObject *args) static PyObject * iobase_check_seekable(PyObject *self, PyObject *args) { - return _PyIOBase_check_seekable(self, args); + _PyIO_State *state = IO_STATE(); + return _PyIOBase_check_seekable(state, self, args); } static PyObject * @@ -390,14 +391,13 @@ _io__IOBase_seekable_impl(PyObject *self) } PyObject * -_PyIOBase_check_seekable(PyObject *self, PyObject *args) +_PyIOBase_check_seekable(_PyIO_State *state, PyObject *self, PyObject *args) { PyObject *res = PyObject_CallMethodNoArgs(self, &_Py_ID(seekable)); if (res == NULL) return NULL; if (res != Py_True) { Py_CLEAR(res); - _PyIO_State *state = IO_STATE(); iobase_unsupported(state, "File or stream is not seekable."); return NULL; } From 0084715e00725c660a796c15cc7f8710ab8061db Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 9 May 2023 18:38:03 +0200 Subject: [PATCH 08/12] Refactor: replace query with parameter Pass module state to _PyIOBase_check_readable() --- Modules/_io/_iomodule.h | 3 ++- Modules/_io/bufferedio.c | 13 ++++++++----- Modules/_io/iobase.c | 6 +++--- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/Modules/_io/_iomodule.h b/Modules/_io/_iomodule.h index 603f2caf31dff0..30299014fbe28b 100644 --- a/Modules/_io/_iomodule.h +++ b/Modules/_io/_iomodule.h @@ -35,7 +35,8 @@ extern PyType_Spec winconsoleio_spec; * BUT when args=Py_True is passed, they return a borrowed reference. */ struct _io_state; // Forward decl. -extern PyObject* _PyIOBase_check_readable(PyObject *self, PyObject *args); +extern PyObject* _PyIOBase_check_readable(struct _io_state *state, + PyObject *self, PyObject *args); extern PyObject* _PyIOBase_check_writable(PyObject *self, PyObject *args); extern PyObject* _PyIOBase_check_seekable(struct _io_state *state, PyObject *self, PyObject *args); diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index be875e017bf29e..d773e975ee2f92 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -1424,8 +1424,10 @@ _io_BufferedReader___init___impl(buffered *self, PyObject *raw, self->ok = 0; self->detached = 0; - if (_PyIOBase_check_readable(raw, Py_True) == NULL) + _PyIO_State *state = find_io_state_by_def(Py_TYPE(self)); + if (_PyIOBase_check_readable(state, raw, Py_True) == NULL) { return -1; + } Py_XSETREF(self->raw, Py_NewRef(raw)); self->buffer_size = buffer_size; @@ -1436,7 +1438,6 @@ _io_BufferedReader___init___impl(buffered *self, PyObject *raw, return -1; _bufferedreader_reset_buf(self); - _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) @@ -2097,12 +2098,13 @@ _io_BufferedRWPair___init___impl(rwpair *self, PyObject *reader, PyObject *writer, Py_ssize_t buffer_size) /*[clinic end generated code: output=327e73d1aee8f984 input=620d42d71f33a031]*/ { - if (_PyIOBase_check_readable(reader, Py_True) == NULL) + _PyIO_State *state = find_io_state_by_def(Py_TYPE(self)); + if (_PyIOBase_check_readable(state, reader, Py_True) == NULL) { return -1; + } 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 *)state->PyBufferedReader_Type, "On", reader, buffer_size); @@ -2299,8 +2301,9 @@ _io_BufferedRandom___init___impl(buffered *self, PyObject *raw, if (_PyIOBase_check_seekable(state, raw, Py_True) == NULL) { return -1; } - if (_PyIOBase_check_readable(raw, Py_True) == NULL) + if (_PyIOBase_check_readable(state, raw, Py_True) == NULL) { return -1; + } if (_PyIOBase_check_writable(raw, Py_True) == NULL) return -1; diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c index 7898fae6c35ec4..fbafdbc48925b4 100644 --- a/Modules/_io/iobase.c +++ b/Modules/_io/iobase.c @@ -214,7 +214,8 @@ iobase_check_seekable(PyObject *self, PyObject *args) static PyObject * iobase_check_readable(PyObject *self, PyObject *args) { - return _PyIOBase_check_readable(self, args); + _PyIO_State *state = IO_STATE(); + return _PyIOBase_check_readable(state, self, args); } static PyObject * @@ -424,14 +425,13 @@ _io__IOBase_readable_impl(PyObject *self) /* May be called with any object */ PyObject * -_PyIOBase_check_readable(PyObject *self, PyObject *args) +_PyIOBase_check_readable(_PyIO_State *state, PyObject *self, PyObject *args) { PyObject *res = PyObject_CallMethodNoArgs(self, &_Py_ID(readable)); if (res == NULL) return NULL; if (res != Py_True) { Py_CLEAR(res); - _PyIO_State *state = IO_STATE(); iobase_unsupported(state, "File or stream is not readable."); return NULL; } From 20777e7d45ebb906653217b4ffd423bfbec2130d Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 9 May 2023 18:40:12 +0200 Subject: [PATCH 09/12] Refactor: replace query with parameter Pass module state to _PyIOBase_check_writable() --- Modules/_io/_iomodule.h | 3 ++- Modules/_io/bufferedio.c | 11 +++++++---- Modules/_io/iobase.c | 6 +++--- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/Modules/_io/_iomodule.h b/Modules/_io/_iomodule.h index 30299014fbe28b..5c6124eb88e21e 100644 --- a/Modules/_io/_iomodule.h +++ b/Modules/_io/_iomodule.h @@ -37,7 +37,8 @@ extern PyType_Spec winconsoleio_spec; struct _io_state; // Forward decl. extern PyObject* _PyIOBase_check_readable(struct _io_state *state, PyObject *self, PyObject *args); -extern PyObject* _PyIOBase_check_writable(PyObject *self, PyObject *args); +extern PyObject* _PyIOBase_check_writable(struct _io_state *state, + PyObject *self, PyObject *args); extern PyObject* _PyIOBase_check_seekable(struct _io_state *state, PyObject *self, PyObject *args); extern PyObject* _PyIOBase_check_closed(PyObject *self, PyObject *args); diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index d773e975ee2f92..98abf7e7345846 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -1780,8 +1780,10 @@ _io_BufferedWriter___init___impl(buffered *self, PyObject *raw, self->ok = 0; self->detached = 0; - if (_PyIOBase_check_writable(raw, Py_True) == NULL) + _PyIO_State *state = find_io_state_by_def(Py_TYPE(self)); + if (_PyIOBase_check_writable(state, raw, Py_True) == NULL) { return -1; + } Py_INCREF(raw); Py_XSETREF(self->raw, raw); @@ -1794,7 +1796,6 @@ _io_BufferedWriter___init___impl(buffered *self, PyObject *raw, _bufferedwriter_reset_buf(self); self->pos = 0; - _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) @@ -2102,8 +2103,9 @@ _io_BufferedRWPair___init___impl(rwpair *self, PyObject *reader, if (_PyIOBase_check_readable(state, reader, Py_True) == NULL) { return -1; } - if (_PyIOBase_check_writable(writer, Py_True) == NULL) + if (_PyIOBase_check_writable(state, writer, Py_True) == NULL) { return -1; + } self->reader = (buffered *) PyObject_CallFunction( (PyObject *)state->PyBufferedReader_Type, @@ -2304,8 +2306,9 @@ _io_BufferedRandom___init___impl(buffered *self, PyObject *raw, if (_PyIOBase_check_readable(state, raw, Py_True) == NULL) { return -1; } - if (_PyIOBase_check_writable(raw, Py_True) == NULL) + if (_PyIOBase_check_writable(state, raw, Py_True) == NULL) { return -1; + } Py_INCREF(raw); Py_XSETREF(self->raw, raw); diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c index fbafdbc48925b4..ca13866c33fba6 100644 --- a/Modules/_io/iobase.c +++ b/Modules/_io/iobase.c @@ -221,7 +221,8 @@ iobase_check_readable(PyObject *self, PyObject *args) static PyObject * iobase_check_writable(PyObject *self, PyObject *args) { - return _PyIOBase_check_writable(self, args); + _PyIO_State *state = IO_STATE(); + return _PyIOBase_check_writable(state, self, args); } /* XXX: IOBase thinks it has to maintain its own internal state in @@ -458,14 +459,13 @@ _io__IOBase_writable_impl(PyObject *self) /* May be called with any object */ PyObject * -_PyIOBase_check_writable(PyObject *self, PyObject *args) +_PyIOBase_check_writable(_PyIO_State *state, PyObject *self, PyObject *args) { PyObject *res = PyObject_CallMethodNoArgs(self, &_Py_ID(writable)); if (res == NULL) return NULL; if (res != Py_True) { Py_CLEAR(res); - _PyIO_State *state = IO_STATE(); iobase_unsupported(state, "File or stream is not writable."); return NULL; } From b22b41d7858ae234fd25ec7e86cee827688cfa7e Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 9 May 2023 22:50:51 +0200 Subject: [PATCH 10/12] Fetch state by module def in _io__Buffered_seek_impl() --- Modules/_io/bufferedio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index 98abf7e7345846..172fafe6db8a3d 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -1224,7 +1224,7 @@ _io__Buffered_seek_impl(buffered *self, PyObject *targetobj, int whence) CHECK_CLOSED(self, "seek of closed file") - _PyIO_State *state = IO_STATE(); + _PyIO_State *state = find_io_state_by_def(Py_TYPE(self)); if (_PyIOBase_check_seekable(state, self->raw, Py_True) == NULL) { return NULL; } From 0044293b1a93f0e4adeb77f48dda0efa3c42c314 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 10 May 2023 00:28:10 +0200 Subject: [PATCH 11/12] Address review: improve forward decl. of _PyIO_State --- Modules/_io/_iomodule.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Modules/_io/_iomodule.h b/Modules/_io/_iomodule.h index 5c6124eb88e21e..b11e5a1849d967 100644 --- a/Modules/_io/_iomodule.h +++ b/Modules/_io/_iomodule.h @@ -34,12 +34,12 @@ extern PyType_Spec winconsoleio_spec; * with args=NULL, and return a new reference. * BUT when args=Py_True is passed, they return a borrowed reference. */ -struct _io_state; // Forward decl. -extern PyObject* _PyIOBase_check_readable(struct _io_state *state, +typedef struct _io_state _PyIO_State; // Forward decl. +extern PyObject* _PyIOBase_check_readable(_PyIO_State *state, PyObject *self, PyObject *args); -extern PyObject* _PyIOBase_check_writable(struct _io_state *state, +extern PyObject* _PyIOBase_check_writable(_PyIO_State *state, PyObject *self, PyObject *args); -extern PyObject* _PyIOBase_check_seekable(struct _io_state *state, +extern PyObject* _PyIOBase_check_seekable(_PyIO_State *state, PyObject *self, PyObject *args); extern PyObject* _PyIOBase_check_closed(PyObject *self, PyObject *args); From 7aa8da76a45c237f80e86a4bd2d0542e8426e395 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 10 May 2023 00:39:52 +0200 Subject: [PATCH 12/12] Address review: remove second typedef It may provoke compiler warnings --- Modules/_io/_iomodule.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/_io/_iomodule.h b/Modules/_io/_iomodule.h index b11e5a1849d967..b3873ddf7e0847 100644 --- a/Modules/_io/_iomodule.h +++ b/Modules/_io/_iomodule.h @@ -144,7 +144,7 @@ extern Py_off_t PyNumber_AsOff_t(PyObject *item, PyObject *err); extern PyModuleDef _PyIO_Module; -typedef struct _io_state { +struct _io_state { int initialized; PyObject *unsupported_operation; @@ -165,7 +165,7 @@ typedef struct _io_state { #ifdef MS_WINDOWS PyTypeObject *PyWindowsConsoleIO_Type; #endif -} _PyIO_State; +}; #define IO_MOD_STATE(mod) ((_PyIO_State *)PyModule_GetState(mod)) #define IO_STATE() _PyIO_get_module_state()