Index: Lib/_pyio.py =================================================================== --- Lib/_pyio.py (révision 85808) +++ Lib/_pyio.py (copie de travail) @@ -747,6 +747,10 @@ def mode(self): return self.raw.mode + def __getstate__(self): + raise TypeError("can not serialize a '{0}' object" + .format(self.__class__.__name__)) + def __repr__(self): clsname = self.__class__.__name__ try: Index: Lib/test/test_io.py =================================================================== --- Lib/test/test_io.py (révision 85808) +++ Lib/test/test_io.py (copie de travail) @@ -29,6 +29,7 @@ import abc import signal import errno +import pickle from itertools import cycle, count from collections import deque from test import support @@ -2525,6 +2526,23 @@ # baseline "io" module. self._check_abc_inheritance(io) + def test_pickling(self): + # Pickling file objects is forbidden + for kwargs in [ + {"mode": "w"}, + {"mode": "wb"}, + {"mode": "wb", "buffering": 0}, + {"mode": "r"}, + {"mode": "rb"}, + {"mode": "rb", "buffering": 0}, + {"mode": "w+"}, + {"mode": "w+b"}, + {"mode": "w+b", "buffering": 0}, + ]: + for protocol in range(pickle.HIGHEST_PROTOCOL + 1): + with self.open(support.TESTFN, **kwargs) as f: + self.assertRaises(TypeError, pickle.dumps, f, protocol) + class CMiscIOTest(MiscIOTest): io = io Index: Modules/_io/fileio.c =================================================================== --- Modules/_io/fileio.c (révision 85808) +++ Modules/_io/fileio.c (copie de travail) @@ -915,7 +915,15 @@ return PyBool_FromLong(res); } +static PyObject * +fileio_getstate(fileio *self) +{ + PyErr_Format(PyExc_TypeError, + "cannot serialize '%s' object", Py_TYPE(self)->tp_name); + return NULL; +} + PyDoc_STRVAR(fileio_doc, "file(name: str[, mode: str]) -> file IO object\n" "\n" @@ -1008,6 +1016,7 @@ {"writable", (PyCFunction)fileio_writable, METH_NOARGS, writable_doc}, {"fileno", (PyCFunction)fileio_fileno, METH_NOARGS, fileno_doc}, {"isatty", (PyCFunction)fileio_isatty, METH_NOARGS, isatty_doc}, + {"__getstate__", (PyCFunction)fileio_getstate, METH_NOARGS, NULL}, {NULL, NULL} /* sentinel */ }; Index: Modules/_io/bufferedio.c =================================================================== --- Modules/_io/bufferedio.c (révision 85808) +++ Modules/_io/bufferedio.c (copie de travail) @@ -522,7 +522,16 @@ return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL); } +/* Serialization */ +static PyObject * +buffered_getstate(buffered *self, PyObject *args) +{ + PyErr_Format(PyExc_TypeError, + "cannot serialize '%s' object", Py_TYPE(self)->tp_name); + return NULL; +} + /* Forward decls */ static PyObject * _bufferedwriter_flush_unlocked(buffered *, int); @@ -1461,6 +1470,7 @@ {"writable", (PyCFunction)buffered_writable, METH_NOARGS}, {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS}, {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS}, + {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS}, {"read", (PyCFunction)buffered_read, METH_VARARGS}, {"peek", (PyCFunction)buffered_peek, METH_VARARGS}, @@ -1843,6 +1853,7 @@ {"writable", (PyCFunction)buffered_writable, METH_NOARGS}, {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS}, {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS}, + {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS}, {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS}, {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS}, @@ -2108,6 +2119,8 @@ {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS}, {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS}, + {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS}, + {NULL, NULL} }; @@ -2227,6 +2240,7 @@ {"writable", (PyCFunction)buffered_writable, METH_NOARGS}, {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS}, {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS}, + {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS}, {"flush", (PyCFunction)buffered_flush, METH_NOARGS}, Index: Modules/_io/textio.c =================================================================== --- Modules/_io/textio.c (révision 85808) +++ Modules/_io/textio.c (copie de travail) @@ -2381,6 +2381,14 @@ } static PyObject * +textiowrapper_getstate(textio *self, PyObject *args) +{ + PyErr_Format(PyExc_TypeError, + "cannot serialize '%s' object", Py_TYPE(self)->tp_name); + return NULL; +} + +static PyObject * textiowrapper_flush(textio *self, PyObject *args) { CHECK_INITIALIZED(self); @@ -2537,6 +2545,7 @@ {"readable", (PyCFunction)textiowrapper_readable, METH_NOARGS}, {"writable", (PyCFunction)textiowrapper_writable, METH_NOARGS}, {"isatty", (PyCFunction)textiowrapper_isatty, METH_NOARGS}, + {"__getstate__", (PyCFunction)textiowrapper_getstate, METH_NOARGS}, {"seek", (PyCFunction)textiowrapper_seek, METH_VARARGS}, {"tell", (PyCFunction)textiowrapper_tell, METH_NOARGS},