diff -r a2f574896f49 Lib/test/test_csv.py --- a/Lib/test/test_csv.py Thu Nov 12 11:34:39 2015 +0200 +++ b/Lib/test/test_csv.py Thu Nov 12 13:09:03 2015 +0200 @@ -1,6 +1,7 @@ # Copyright (C) 2001,2002 Python Software Foundation # csv package unit tests +import copy import io import sys import os @@ -9,6 +10,7 @@ from io import StringIO from tempfile import TemporaryFile import csv import gc +import pickle from test import support class Test_Csv(unittest.TestCase): @@ -424,6 +426,17 @@ class TestDialectRegistry(unittest.TestC self.assertRaises(TypeError, csv.reader, [], quoting = -1) self.assertRaises(TypeError, csv.reader, [], quoting = 100) + def test_copy(self): + for name in csv.list_dialects(): + dialect = csv.get_dialect(name) + self.assertRaises(TypeError, copy.copy, dialect) + + def test_pickle(self): + for name in csv.list_dialects(): + dialect = csv.get_dialect(name) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.assertRaises(TypeError, pickle.dumps, dialect, proto) + class TestCsvBase(unittest.TestCase): def readerAssertEqual(self, input, expected_result): with TemporaryFile("w+", newline='') as fileobj: diff -r a2f574896f49 Lib/test/test_memoryview.py --- a/Lib/test/test_memoryview.py Thu Nov 12 11:34:39 2015 +0200 +++ b/Lib/test/test_memoryview.py Thu Nov 12 13:09:03 2015 +0200 @@ -11,6 +11,8 @@ import gc import weakref import array import io +import copy +import pickle class AbstractMemoryTests: @@ -519,6 +521,17 @@ class OtherTest(unittest.TestCase): m2 = m1[::-1] self.assertEqual(m2.hex(), '30' * 200000) + def test_copy(self): + m = memoryview(b'abc') + with self.assertRaises(TypeError): + copy.copy(m) + + def test_pickle(self): + m = memoryview(b'abc') + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.assertRaises(TypeError): + pickle.dumps(m, proto) + if __name__ == "__main__": unittest.main() diff -r a2f574896f49 Objects/typeobject.c --- a/Objects/typeobject.c Thu Nov 12 11:34:39 2015 +0200 +++ b/Objects/typeobject.c Thu Nov 12 13:09:03 2015 +0200 @@ -4100,6 +4100,16 @@ Py_LOCAL(int) return 0; } +/* Returns 1 if all superclasses of t are allocated on the heap. */ +static int +allheaptypes(PyTypeObject *t) +{ + for (; t != &PyBaseObject_Type; t = t->tp_base) + if (!PyType_HasFeature(t, Py_TPFLAGS_HEAPTYPE)) + return 0; + return 1; +} + static PyObject * reduce_newobj(PyObject *obj) { @@ -4118,6 +4128,18 @@ reduce_newobj(PyObject *obj) return NULL; if (args == NULL) { + if (!PyList_Check(obj) && !PyDict_Check(obj) && + !allheaptypes(Py_TYPE(obj))) { + _Py_IDENTIFIER(__getstate__); + PyObject *getstate = _PyObject_LookupSpecial(obj, &PyId___getstate__); + if (getstate == NULL) { + PyErr_Format(PyExc_TypeError, + "can't pickle %s objects", + Py_TYPE(obj)->tp_name); + return NULL; + } + Py_DECREF(getstate); + } args = PyTuple_New(0); if (args == NULL) { Py_XDECREF(kwargs);