Skip to content

Commit 0353b4e

Browse files
bpo-33138: Change standard error message for non-pickleable and non-copyable types. (GH-6239)
1 parent 3f819ca commit 0353b4e

File tree

11 files changed

+17
-91
lines changed

11 files changed

+17
-91
lines changed

Lib/_pyio.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -814,8 +814,7 @@ def mode(self):
814814
return self.raw.mode
815815

816816
def __getstate__(self):
817-
raise TypeError("can not serialize a '{0}' object"
818-
.format(self.__class__.__name__))
817+
raise TypeError(f"cannot pickle {self.__class__.__name__!r} object")
819818

820819
def __repr__(self):
821820
modname = self.__class__.__module__
@@ -1554,7 +1553,7 @@ def __del__(self):
15541553
self.close()
15551554

15561555
def __getstate__(self):
1557-
raise TypeError("cannot serialize '%s' object", self.__class__.__name__)
1556+
raise TypeError(f"cannot pickle {self.__class__.__name__!r} object")
15581557

15591558
def __repr__(self):
15601559
class_name = '%s.%s' % (self.__class__.__module__,

Lib/copyreg.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,24 +53,27 @@ def _reconstructor(cls, base, state):
5353

5454
def _reduce_ex(self, proto):
5555
assert proto < 2
56-
for base in self.__class__.__mro__:
56+
cls = self.__class__
57+
for base in cls.__mro__:
5758
if hasattr(base, '__flags__') and not base.__flags__ & _HEAPTYPE:
5859
break
5960
else:
6061
base = object # not really reachable
6162
if base is object:
6263
state = None
6364
else:
64-
if base is self.__class__:
65-
raise TypeError("can't pickle %s objects" % base.__name__)
65+
if base is cls:
66+
raise TypeError(f"cannot pickle {cls.__name__!r} object")
6667
state = base(self)
67-
args = (self.__class__, base, state)
68+
args = (cls, base, state)
6869
try:
6970
getstate = self.__getstate__
7071
except AttributeError:
7172
if getattr(self, "__slots__", None):
72-
raise TypeError("a class that defines __slots__ without "
73-
"defining __getstate__ cannot be pickled") from None
73+
raise TypeError(f"cannot pickle {cls.__name__!r} object: "
74+
f"a class that defines __slots__ without "
75+
f"defining __getstate__ cannot be pickled "
76+
f"with protocol {proto}") from None
7477
try:
7578
dict = self.__dict__
7679
except AttributeError:

Lib/socket.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ def __repr__(self):
189189
return s
190190

191191
def __getstate__(self):
192-
raise TypeError("Cannot serialize socket object")
192+
raise TypeError(f"cannot pickle {self.__class__.__name__!r} object")
193193

194194
def dup(self):
195195
"""dup() -> socket object
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Changed standard error message for non-pickleable and non-copyable types. It
2+
now says "cannot pickle" instead of "can't pickle" or "cannot serialize".

Modules/_bz2module.c

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -264,14 +264,6 @@ _bz2_BZ2Compressor_flush_impl(BZ2Compressor *self)
264264
return result;
265265
}
266266

267-
static PyObject *
268-
BZ2Compressor_getstate(BZ2Compressor *self, PyObject *noargs)
269-
{
270-
PyErr_Format(PyExc_TypeError, "cannot serialize '%s' object",
271-
Py_TYPE(self)->tp_name);
272-
return NULL;
273-
}
274-
275267
static void*
276268
BZ2_Malloc(void* ctx, int items, int size)
277269
{
@@ -347,7 +339,6 @@ BZ2Compressor_dealloc(BZ2Compressor *self)
347339
static PyMethodDef BZ2Compressor_methods[] = {
348340
_BZ2_BZ2COMPRESSOR_COMPRESS_METHODDEF
349341
_BZ2_BZ2COMPRESSOR_FLUSH_METHODDEF
350-
{"__getstate__", (PyCFunction)BZ2Compressor_getstate, METH_NOARGS},
351342
{NULL}
352343
};
353344

@@ -612,14 +603,6 @@ _bz2_BZ2Decompressor_decompress_impl(BZ2Decompressor *self, Py_buffer *data,
612603
return result;
613604
}
614605

615-
static PyObject *
616-
BZ2Decompressor_getstate(BZ2Decompressor *self, PyObject *noargs)
617-
{
618-
PyErr_Format(PyExc_TypeError, "cannot serialize '%s' object",
619-
Py_TYPE(self)->tp_name);
620-
return NULL;
621-
}
622-
623606
/*[clinic input]
624607
_bz2.BZ2Decompressor.__init__
625608
@@ -679,7 +662,6 @@ BZ2Decompressor_dealloc(BZ2Decompressor *self)
679662

680663
static PyMethodDef BZ2Decompressor_methods[] = {
681664
_BZ2_BZ2DECOMPRESSOR_DECOMPRESS_METHODDEF
682-
{"__getstate__", (PyCFunction)BZ2Decompressor_getstate, METH_NOARGS},
683665
{NULL}
684666
};
685667

Modules/_io/bufferedio.c

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -608,16 +608,6 @@ buffered_isatty(buffered *self, PyObject *Py_UNUSED(ignored))
608608
return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
609609
}
610610

611-
/* Serialization */
612-
613-
static PyObject *
614-
buffered_getstate(buffered *self, PyObject *Py_UNUSED(ignored))
615-
{
616-
PyErr_Format(PyExc_TypeError,
617-
"cannot serialize '%s' object", Py_TYPE(self)->tp_name);
618-
return NULL;
619-
}
620-
621611
/* Forward decls */
622612
static PyObject *
623613
_bufferedwriter_flush_unlocked(buffered *);
@@ -2394,7 +2384,6 @@ static PyMethodDef bufferedreader_methods[] = {
23942384
{"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
23952385
{"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
23962386
{"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
2397-
{"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
23982387

23992388
_IO__BUFFERED_READ_METHODDEF
24002389
_IO__BUFFERED_PEEK_METHODDEF
@@ -2485,7 +2474,6 @@ static PyMethodDef bufferedwriter_methods[] = {
24852474
{"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
24862475
{"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
24872476
{"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
2488-
{"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
24892477

24902478
_IO_BUFFEREDWRITER_WRITE_METHODDEF
24912479
_IO__BUFFERED_TRUNCATE_METHODDEF
@@ -2579,8 +2567,6 @@ static PyMethodDef bufferedrwpair_methods[] = {
25792567
{"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
25802568
{"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
25812569

2582-
{"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2583-
25842570
{NULL, NULL}
25852571
};
25862572

@@ -2652,7 +2638,6 @@ static PyMethodDef bufferedrandom_methods[] = {
26522638
{"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
26532639
{"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
26542640
{"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
2655-
{"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
26562641

26572642
{"flush", (PyCFunction)buffered_flush, METH_NOARGS},
26582643

Modules/_io/fileio.c

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,14 +1120,6 @@ _io_FileIO_isatty_impl(fileio *self)
11201120
return PyBool_FromLong(res);
11211121
}
11221122

1123-
static PyObject *
1124-
fileio_getstate(fileio *self, PyObject *Py_UNUSED(ignored))
1125-
{
1126-
PyErr_Format(PyExc_TypeError,
1127-
"cannot serialize '%s' object", Py_TYPE(self)->tp_name);
1128-
return NULL;
1129-
}
1130-
11311123
#include "clinic/fileio.c.h"
11321124

11331125
static PyMethodDef fileio_methods[] = {
@@ -1145,7 +1137,6 @@ static PyMethodDef fileio_methods[] = {
11451137
_IO_FILEIO_FILENO_METHODDEF
11461138
_IO_FILEIO_ISATTY_METHODDEF
11471139
{"_dealloc_warn", (PyCFunction)fileio_dealloc_warn, METH_O, NULL},
1148-
{"__getstate__", (PyCFunction)fileio_getstate, METH_NOARGS, NULL},
11491140
{NULL, NULL} /* sentinel */
11501141
};
11511142

Modules/_io/textio.c

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2891,14 +2891,6 @@ _io_TextIOWrapper_isatty_impl(textio *self)
28912891
return _PyObject_CallMethodId(self->buffer, &PyId_isatty, NULL);
28922892
}
28932893

2894-
static PyObject *
2895-
textiowrapper_getstate(textio *self, PyObject *args)
2896-
{
2897-
PyErr_Format(PyExc_TypeError,
2898-
"cannot serialize '%s' object", Py_TYPE(self)->tp_name);
2899-
return NULL;
2900-
}
2901-
29022894
/*[clinic input]
29032895
_io.TextIOWrapper.flush
29042896
[clinic start generated code]*/
@@ -3132,7 +3124,6 @@ static PyMethodDef textiowrapper_methods[] = {
31323124
_IO_TEXTIOWRAPPER_READABLE_METHODDEF
31333125
_IO_TEXTIOWRAPPER_WRITABLE_METHODDEF
31343126
_IO_TEXTIOWRAPPER_ISATTY_METHODDEF
3135-
{"__getstate__", (PyCFunction)textiowrapper_getstate, METH_NOARGS},
31363127

31373128
_IO_TEXTIOWRAPPER_SEEK_METHODDEF
31383129
_IO_TEXTIOWRAPPER_TELL_METHODDEF

Modules/_io/winconsoleio.c

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1060,14 +1060,6 @@ _io__WindowsConsoleIO_isatty_impl(winconsoleio *self)
10601060
Py_RETURN_TRUE;
10611061
}
10621062

1063-
static PyObject *
1064-
winconsoleio_getstate(winconsoleio *self, PyObject *Py_UNUSED(ignored))
1065-
{
1066-
PyErr_Format(PyExc_TypeError,
1067-
"cannot serialize '%s' object", Py_TYPE(self)->tp_name);
1068-
return NULL;
1069-
}
1070-
10711063
#include "clinic/winconsoleio.c.h"
10721064

10731065
static PyMethodDef winconsoleio_methods[] = {
@@ -1080,7 +1072,6 @@ static PyMethodDef winconsoleio_methods[] = {
10801072
_IO__WINDOWSCONSOLEIO_WRITABLE_METHODDEF
10811073
_IO__WINDOWSCONSOLEIO_FILENO_METHODDEF
10821074
_IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF
1083-
{"__getstate__", (PyCFunction)winconsoleio_getstate, METH_NOARGS, NULL},
10841075
{NULL, NULL} /* sentinel */
10851076
};
10861077

Modules/_lzmamodule.c

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -591,14 +591,6 @@ _lzma_LZMACompressor_flush_impl(Compressor *self)
591591
return result;
592592
}
593593

594-
static PyObject *
595-
Compressor_getstate(Compressor *self, PyObject *noargs)
596-
{
597-
PyErr_Format(PyExc_TypeError, "cannot serialize '%s' object",
598-
Py_TYPE(self)->tp_name);
599-
return NULL;
600-
}
601-
602594
static int
603595
Compressor_init_xz(lzma_stream *lzs, int check, uint32_t preset,
604596
PyObject *filterspecs)
@@ -794,7 +786,6 @@ Compressor_dealloc(Compressor *self)
794786
static PyMethodDef Compressor_methods[] = {
795787
_LZMA_LZMACOMPRESSOR_COMPRESS_METHODDEF
796788
_LZMA_LZMACOMPRESSOR_FLUSH_METHODDEF
797-
{"__getstate__", (PyCFunction)Compressor_getstate, METH_NOARGS},
798789
{NULL}
799790
};
800791

@@ -1078,14 +1069,6 @@ _lzma_LZMADecompressor_decompress_impl(Decompressor *self, Py_buffer *data,
10781069
return result;
10791070
}
10801071

1081-
static PyObject *
1082-
Decompressor_getstate(Decompressor *self, PyObject *noargs)
1083-
{
1084-
PyErr_Format(PyExc_TypeError, "cannot serialize '%s' object",
1085-
Py_TYPE(self)->tp_name);
1086-
return NULL;
1087-
}
1088-
10891072
static int
10901073
Decompressor_init_raw(lzma_stream *lzs, PyObject *filterspecs)
10911074
{
@@ -1235,7 +1218,6 @@ Decompressor_dealloc(Decompressor *self)
12351218

12361219
static PyMethodDef Decompressor_methods[] = {
12371220
_LZMA_LZMADECOMPRESSOR_DECOMPRESS_METHODDEF
1238-
{"__getstate__", (PyCFunction)Decompressor_getstate, METH_NOARGS},
12391221
{NULL}
12401222
};
12411223

Objects/typeobject.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4122,7 +4122,7 @@ _PyObject_GetState(PyObject *obj, int required)
41224122

41234123
if (required && obj->ob_type->tp_itemsize) {
41244124
PyErr_Format(PyExc_TypeError,
4125-
"can't pickle %.200s objects",
4125+
"cannot pickle '%.200s' object",
41264126
Py_TYPE(obj)->tp_name);
41274127
return NULL;
41284128
}
@@ -4163,7 +4163,7 @@ _PyObject_GetState(PyObject *obj, int required)
41634163
Py_DECREF(slotnames);
41644164
Py_DECREF(state);
41654165
PyErr_Format(PyExc_TypeError,
4166-
"can't pickle %.200s objects",
4166+
"cannot pickle '%.200s' object",
41674167
Py_TYPE(obj)->tp_name);
41684168
return NULL;
41694169
}
@@ -4400,7 +4400,7 @@ reduce_newobj(PyObject *obj)
44004400

44014401
if (Py_TYPE(obj)->tp_new == NULL) {
44024402
PyErr_Format(PyExc_TypeError,
4403-
"can't pickle %.200s objects",
4403+
"cannot pickle '%.200s' object",
44044404
Py_TYPE(obj)->tp_name);
44054405
return NULL;
44064406
}

0 commit comments

Comments
 (0)