Issue #10180: Pickling file objects is now explicitly forbidden, since
unpickling them produced nonsensical results.
This commit is contained in:
parent
4a5f9677f3
commit
243757eb79
@ -747,6 +747,10 @@ class _BufferedIOMixin(BufferedIOBase):
|
|||||||
def mode(self):
|
def mode(self):
|
||||||
return self.raw.mode
|
return self.raw.mode
|
||||||
|
|
||||||
|
def __getstate__(self):
|
||||||
|
raise TypeError("can not serialize a '{0}' object"
|
||||||
|
.format(self.__class__.__name__))
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
clsname = self.__class__.__name__
|
clsname = self.__class__.__name__
|
||||||
try:
|
try:
|
||||||
|
@ -30,6 +30,7 @@ import abc
|
|||||||
import signal
|
import signal
|
||||||
import errno
|
import errno
|
||||||
import warnings
|
import warnings
|
||||||
|
import pickle
|
||||||
from itertools import cycle, count
|
from itertools import cycle, count
|
||||||
from collections import deque
|
from collections import deque
|
||||||
from test import support
|
from test import support
|
||||||
@ -2566,6 +2567,23 @@ class MiscIOTest(unittest.TestCase):
|
|||||||
self._check_warn_on_dealloc_fd("r")
|
self._check_warn_on_dealloc_fd("r")
|
||||||
|
|
||||||
|
|
||||||
|
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):
|
class CMiscIOTest(MiscIOTest):
|
||||||
io = io
|
io = io
|
||||||
|
|
||||||
|
@ -65,6 +65,9 @@ Core and Builtins
|
|||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #10180: Pickling file objects is now explicitly forbidden, since
|
||||||
|
unpickling them produced nonsensical results.
|
||||||
|
|
||||||
- Issue #10311: The signal module now restores errno before returning from
|
- Issue #10311: The signal module now restores errno before returning from
|
||||||
its low-level signal handler. Patch by Hallvard B Furuseth.
|
its low-level signal handler. Patch by Hallvard B Furuseth.
|
||||||
|
|
||||||
|
@ -549,6 +549,15 @@ buffered_isatty(buffered *self, PyObject *args)
|
|||||||
return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
|
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 */
|
/* Forward decls */
|
||||||
static PyObject *
|
static PyObject *
|
||||||
@ -1489,6 +1498,7 @@ static PyMethodDef bufferedreader_methods[] = {
|
|||||||
{"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
|
{"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
|
||||||
{"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
|
{"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
|
||||||
{"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
|
{"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
|
||||||
|
{"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
|
||||||
|
|
||||||
{"read", (PyCFunction)buffered_read, METH_VARARGS},
|
{"read", (PyCFunction)buffered_read, METH_VARARGS},
|
||||||
{"peek", (PyCFunction)buffered_peek, METH_VARARGS},
|
{"peek", (PyCFunction)buffered_peek, METH_VARARGS},
|
||||||
@ -1872,6 +1882,7 @@ static PyMethodDef bufferedwriter_methods[] = {
|
|||||||
{"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
|
{"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
|
||||||
{"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
|
{"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
|
||||||
{"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
|
{"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
|
||||||
|
{"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
|
||||||
|
|
||||||
{"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
|
{"write", (PyCFunction)bufferedwriter_write, METH_VARARGS},
|
||||||
{"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
|
{"truncate", (PyCFunction)buffered_truncate, METH_VARARGS},
|
||||||
@ -2137,6 +2148,8 @@ static PyMethodDef bufferedrwpair_methods[] = {
|
|||||||
{"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
|
{"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
|
||||||
{"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
|
{"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
|
||||||
|
|
||||||
|
{"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
|
||||||
|
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2257,6 +2270,7 @@ static PyMethodDef bufferedrandom_methods[] = {
|
|||||||
{"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
|
{"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
|
||||||
{"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
|
{"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
|
||||||
{"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
|
{"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
|
||||||
|
{"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
|
||||||
|
|
||||||
{"flush", (PyCFunction)buffered_flush, METH_NOARGS},
|
{"flush", (PyCFunction)buffered_flush, METH_NOARGS},
|
||||||
|
|
||||||
|
@ -952,6 +952,14 @@ fileio_isatty(fileio *self)
|
|||||||
return PyBool_FromLong(res);
|
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,
|
PyDoc_STRVAR(fileio_doc,
|
||||||
"file(name: str[, mode: str]) -> file IO object\n"
|
"file(name: str[, mode: str]) -> file IO object\n"
|
||||||
@ -1046,6 +1054,7 @@ static PyMethodDef fileio_methods[] = {
|
|||||||
{"fileno", (PyCFunction)fileio_fileno, METH_NOARGS, fileno_doc},
|
{"fileno", (PyCFunction)fileio_fileno, METH_NOARGS, fileno_doc},
|
||||||
{"isatty", (PyCFunction)fileio_isatty, METH_NOARGS, isatty_doc},
|
{"isatty", (PyCFunction)fileio_isatty, METH_NOARGS, isatty_doc},
|
||||||
{"_dealloc_warn", (PyCFunction)fileio_dealloc_warn, METH_O, NULL},
|
{"_dealloc_warn", (PyCFunction)fileio_dealloc_warn, METH_O, NULL},
|
||||||
|
{"__getstate__", (PyCFunction)fileio_getstate, METH_NOARGS, NULL},
|
||||||
{NULL, NULL} /* sentinel */
|
{NULL, NULL} /* sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2382,6 +2382,14 @@ textiowrapper_isatty(textio *self, PyObject *args)
|
|||||||
return PyObject_CallMethod(self->buffer, "isatty", NULL);
|
return PyObject_CallMethod(self->buffer, "isatty", NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 *
|
static PyObject *
|
||||||
textiowrapper_flush(textio *self, PyObject *args)
|
textiowrapper_flush(textio *self, PyObject *args)
|
||||||
{
|
{
|
||||||
@ -2546,6 +2554,7 @@ static PyMethodDef textiowrapper_methods[] = {
|
|||||||
{"readable", (PyCFunction)textiowrapper_readable, METH_NOARGS},
|
{"readable", (PyCFunction)textiowrapper_readable, METH_NOARGS},
|
||||||
{"writable", (PyCFunction)textiowrapper_writable, METH_NOARGS},
|
{"writable", (PyCFunction)textiowrapper_writable, METH_NOARGS},
|
||||||
{"isatty", (PyCFunction)textiowrapper_isatty, METH_NOARGS},
|
{"isatty", (PyCFunction)textiowrapper_isatty, METH_NOARGS},
|
||||||
|
{"__getstate__", (PyCFunction)textiowrapper_getstate, METH_NOARGS},
|
||||||
|
|
||||||
{"seek", (PyCFunction)textiowrapper_seek, METH_VARARGS},
|
{"seek", (PyCFunction)textiowrapper_seek, METH_VARARGS},
|
||||||
{"tell", (PyCFunction)textiowrapper_tell, METH_NOARGS},
|
{"tell", (PyCFunction)textiowrapper_tell, METH_NOARGS},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user