Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit fe8c256

Browse files
Pass state to _check* functions
Also remove them as private methods on the private iobase type
1 parent 916ae8c commit fe8c256

4 files changed

Lines changed: 30 additions & 34 deletions

File tree

Lib/test/test_io.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4242,6 +4242,7 @@ def test_warn_on_dealloc_fd(self):
42424242

42434243
def test_pickling(self):
42444244
# Pickling file objects is forbidden
4245+
msg = "cannot pickle"
42454246
for kwargs in [
42464247
{"mode": "w"},
42474248
{"mode": "wb"},
@@ -4256,8 +4257,10 @@ def test_pickling(self):
42564257
if "b" not in kwargs["mode"]:
42574258
kwargs["encoding"] = "utf-8"
42584259
for protocol in range(pickle.HIGHEST_PROTOCOL + 1):
4259-
with self.open(os_helper.TESTFN, **kwargs) as f:
4260-
self.assertRaises(TypeError, pickle.dumps, f, protocol)
4260+
with self.subTest(protocol=protocol, kwargs=kwargs):
4261+
with self.open(os_helper.TESTFN, **kwargs) as f:
4262+
with self.assertRaisesRegex(TypeError, msg):
4263+
pickle.dumps(f, protocol)
42614264

42624265
@unittest.skipIf(
42634266
support.is_emscripten, "fstat() of a pipe fd is not supported"

Modules/_io/_iomodule.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,6 @@ extern PyType_Spec textiowrapper_spec;
2626
extern PyType_Spec winconsoleio_spec;
2727
#endif
2828

29-
/* These functions are used as METH_NOARGS methods, are normally called
30-
* with args=NULL, and return a new reference.
31-
* BUT when args=Py_True is passed, they return a borrowed reference.
32-
*/
33-
extern PyObject* _PyIOBase_check_readable(PyObject *self, PyObject *args);
34-
extern PyObject* _PyIOBase_check_writable(PyObject *self, PyObject *args);
35-
extern PyObject* _PyIOBase_check_seekable(PyObject *self, PyObject *args);
36-
extern PyObject* _PyIOBase_check_closed(PyObject *self, PyObject *args);
37-
3829
/* Helper for finalization.
3930
This function will revive an object ready to be deallocated and try to
4031
close() it. It returns 0 if the object can be destroyed, or -1 if it
@@ -185,6 +176,15 @@ find_io_state_by_def(PyTypeObject *type)
185176
return get_io_state(mod);
186177
}
187178

179+
/* These functions are used as METH_NOARGS methods, are normally called
180+
* with args=NULL, and return a new reference.
181+
* BUT when args=Py_True is passed, they return a borrowed reference.
182+
*/
183+
extern PyObject* _PyIOBase_check_readable(_PyIO_State *state, PyObject *self, PyObject *args);
184+
extern PyObject* _PyIOBase_check_writable(_PyIO_State *state, PyObject *self, PyObject *args);
185+
extern PyObject* _PyIOBase_check_seekable(_PyIO_State *state, PyObject *self, PyObject *args);
186+
extern PyObject* _PyIOBase_check_closed(PyObject *self, PyObject *args);
187+
188188
#ifdef MS_WINDOWS
189189
extern char _PyIO_get_console_type(PyObject *);
190190
#endif

Modules/_io/bufferedio.c

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1229,7 +1229,8 @@ _io__Buffered_seek_impl(buffered *self, PyObject *targetobj, int whence)
12291229

12301230
CHECK_CLOSED(self, "seek of closed file")
12311231

1232-
if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1232+
_PyIO_State *state = find_io_state_by_def(Py_TYPE(self));
1233+
if (_PyIOBase_check_seekable(state, self->raw, Py_True) == NULL)
12331234
return NULL;
12341235

12351236
target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
@@ -1428,7 +1429,8 @@ _io_BufferedReader___init___impl(buffered *self, PyObject *raw,
14281429
self->ok = 0;
14291430
self->detached = 0;
14301431

1431-
if (_PyIOBase_check_readable(raw, Py_True) == NULL)
1432+
_PyIO_State *state = find_io_state_by_def(Py_TYPE(self));
1433+
if (_PyIOBase_check_readable(state, raw, Py_True) == NULL)
14321434
return -1;
14331435

14341436
Py_XSETREF(self->raw, Py_NewRef(raw));
@@ -1440,7 +1442,6 @@ _io_BufferedReader___init___impl(buffered *self, PyObject *raw,
14401442
return -1;
14411443
_bufferedreader_reset_buf(self);
14421444

1443-
_PyIO_State *state = find_io_state_by_def(Py_TYPE(self));
14441445
self->fast_closed_checks = (
14451446
Py_IS_TYPE(self, state->PyBufferedReader_Type) &&
14461447
Py_IS_TYPE(raw, state->PyFileIO_Type)
@@ -1784,7 +1785,8 @@ _io_BufferedWriter___init___impl(buffered *self, PyObject *raw,
17841785
self->ok = 0;
17851786
self->detached = 0;
17861787

1787-
if (_PyIOBase_check_writable(raw, Py_True) == NULL)
1788+
_PyIO_State *state = find_io_state_by_def(Py_TYPE(self));
1789+
if (_PyIOBase_check_writable(state, raw, Py_True) == NULL)
17881790
return -1;
17891791

17901792
Py_INCREF(raw);
@@ -1798,7 +1800,6 @@ _io_BufferedWriter___init___impl(buffered *self, PyObject *raw,
17981800
_bufferedwriter_reset_buf(self);
17991801
self->pos = 0;
18001802

1801-
_PyIO_State *state = find_io_state_by_def(Py_TYPE(self));
18021803
self->fast_closed_checks = (
18031804
Py_IS_TYPE(self, state->PyBufferedWriter_Type) &&
18041805
Py_IS_TYPE(raw, state->PyFileIO_Type)
@@ -2103,12 +2104,12 @@ _io_BufferedRWPair___init___impl(rwpair *self, PyObject *reader,
21032104
PyObject *writer, Py_ssize_t buffer_size)
21042105
/*[clinic end generated code: output=327e73d1aee8f984 input=620d42d71f33a031]*/
21052106
{
2106-
if (_PyIOBase_check_readable(reader, Py_True) == NULL)
2107+
_PyIO_State *state = find_io_state_by_def(Py_TYPE(self));
2108+
if (_PyIOBase_check_readable(state, reader, Py_True) == NULL)
21072109
return -1;
2108-
if (_PyIOBase_check_writable(writer, Py_True) == NULL)
2110+
if (_PyIOBase_check_writable(state, writer, Py_True) == NULL)
21092111
return -1;
21102112

2111-
_PyIO_State *state = find_io_state_by_def(Py_TYPE(self));
21122113
self->reader = (buffered *) PyObject_CallFunction(
21132114
(PyObject *)state->PyBufferedReader_Type,
21142115
"On", reader, buffer_size);
@@ -2300,11 +2301,12 @@ _io_BufferedRandom___init___impl(buffered *self, PyObject *raw,
23002301
self->ok = 0;
23012302
self->detached = 0;
23022303

2303-
if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
2304+
_PyIO_State *state = find_io_state_by_def(Py_TYPE(self));
2305+
if (_PyIOBase_check_seekable(state, raw, Py_True) == NULL)
23042306
return -1;
2305-
if (_PyIOBase_check_readable(raw, Py_True) == NULL)
2307+
if (_PyIOBase_check_readable(state, raw, Py_True) == NULL)
23062308
return -1;
2307-
if (_PyIOBase_check_writable(raw, Py_True) == NULL)
2309+
if (_PyIOBase_check_writable(state, raw, Py_True) == NULL)
23082310
return -1;
23092311

23102312
Py_INCREF(raw);
@@ -2319,7 +2321,6 @@ _io_BufferedRandom___init___impl(buffered *self, PyObject *raw,
23192321
_bufferedwriter_reset_buf(self);
23202322
self->pos = 0;
23212323

2322-
_PyIO_State *state = find_io_state_by_def(Py_TYPE(self));
23232324
self->fast_closed_checks = (Py_IS_TYPE(self, state->PyBufferedRandom_Type) &&
23242325
Py_IS_TYPE(raw, state->PyFileIO_Type));
23252326

Modules/_io/iobase.c

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -377,14 +377,13 @@ _io__IOBase_seekable_impl(PyObject *self)
377377
}
378378

379379
PyObject *
380-
_PyIOBase_check_seekable(PyObject *self, PyObject *args)
380+
_PyIOBase_check_seekable(_PyIO_State *state, PyObject *self, PyObject *args)
381381
{
382382
PyObject *res = PyObject_CallMethodNoArgs(self, &_Py_ID(seekable));
383383
if (res == NULL)
384384
return NULL;
385385
if (res != Py_True) {
386386
Py_CLEAR(res);
387-
_PyIO_State *state = find_io_state_by_def(Py_TYPE(self));
388387
iobase_unsupported(state, "File or stream is not seekable.");
389388
return NULL;
390389
}
@@ -411,14 +410,13 @@ _io__IOBase_readable_impl(PyObject *self)
411410

412411
/* May be called with any object */
413412
PyObject *
414-
_PyIOBase_check_readable(PyObject *self, PyObject *args)
413+
_PyIOBase_check_readable(_PyIO_State *state, PyObject *self, PyObject *args)
415414
{
416415
PyObject *res = PyObject_CallMethodNoArgs(self, &_Py_ID(readable));
417416
if (res == NULL)
418417
return NULL;
419418
if (res != Py_True) {
420419
Py_CLEAR(res);
421-
_PyIO_State *state = find_io_state_by_def(Py_TYPE(self));
422420
iobase_unsupported(state, "File or stream is not readable.");
423421
return NULL;
424422
}
@@ -445,14 +443,13 @@ _io__IOBase_writable_impl(PyObject *self)
445443

446444
/* May be called with any object */
447445
PyObject *
448-
_PyIOBase_check_writable(PyObject *self, PyObject *args)
446+
_PyIOBase_check_writable(_PyIO_State *state, PyObject *self, PyObject *args)
449447
{
450448
PyObject *res = PyObject_CallMethodNoArgs(self, &_Py_ID(writable));
451449
if (res == NULL)
452450
return NULL;
453451
if (res != Py_True) {
454452
Py_CLEAR(res);
455-
_PyIO_State *state = find_io_state_by_def(Py_TYPE(self));
456453
iobase_unsupported(state, "File or stream is not writable.");
457454
return NULL;
458455
}
@@ -811,11 +808,6 @@ static PyMethodDef iobase_methods[] = {
811808
_IO__IOBASE_READABLE_METHODDEF
812809
_IO__IOBASE_WRITABLE_METHODDEF
813810

814-
{"_checkClosed", _PyIOBase_check_closed, METH_NOARGS},
815-
{"_checkSeekable", _PyIOBase_check_seekable, METH_NOARGS},
816-
{"_checkReadable", _PyIOBase_check_readable, METH_NOARGS},
817-
{"_checkWritable", _PyIOBase_check_writable, METH_NOARGS},
818-
819811
_IO__IOBASE_FILENO_METHODDEF
820812
_IO__IOBASE_ISATTY_METHODDEF
821813

0 commit comments

Comments
 (0)