Commit 5bc51d04 authored by Serhiy Storchaka's avatar Serhiy Storchaka

Issue #22995: Default implementation of __reduce__ and __reduce_ex__ now

rejects builtin types with not defined __new__.
Added tests for non-pickleable types.
parent 5a035f15
import copy
import pickle
import unittest import unittest
from test import support from test import support
...@@ -198,6 +200,22 @@ class DictSetTest(unittest.TestCase): ...@@ -198,6 +200,22 @@ class DictSetTest(unittest.TestCase):
d[42] = d.values() d[42] = d.values()
self.assertRaises(RuntimeError, repr, d) self.assertRaises(RuntimeError, repr, d)
def test_copy(self):
d = {1: 10, "a": "ABC"}
self.assertRaises(TypeError, copy.copy, d.keys())
self.assertRaises(TypeError, copy.copy, d.values())
self.assertRaises(TypeError, copy.copy, d.items())
def test_pickle(self):
d = {1: 10, "a": "ABC"}
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
self.assertRaises((TypeError, pickle.PicklingError),
pickle.dumps, d.keys(), proto)
self.assertRaises((TypeError, pickle.PicklingError),
pickle.dumps, d.values(), proto)
self.assertRaises((TypeError, pickle.PicklingError),
pickle.dumps, d.items(), proto)
def test_main(): def test_main():
support.run_unittest(DictSetTest) support.run_unittest(DictSetTest)
......
import copy
import gc import gc
import pickle
import sys import sys
import unittest import unittest
import weakref import weakref
...@@ -70,6 +72,24 @@ class FinalizationTest(unittest.TestCase): ...@@ -70,6 +72,24 @@ class FinalizationTest(unittest.TestCase):
self.assertEqual(cm.exception.value, 2) self.assertEqual(cm.exception.value, 2)
class GeneratorTest(unittest.TestCase):
def test_copy(self):
def f():
yield 1
g = f()
with self.assertRaises(TypeError):
copy.copy(g)
def test_pickle(self):
def f():
yield 1
g = f()
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
with self.assertRaises((TypeError, pickle.PicklingError)):
pickle.dumps(g, proto)
class ExceptionTest(unittest.TestCase): class ExceptionTest(unittest.TestCase):
# Tests for the issue #23353: check that the currently handled exception # Tests for the issue #23353: check that the currently handled exception
# is correctly saved/restored in PyEval_EvalFrameEx(). # is correctly saved/restored in PyEval_EvalFrameEx().
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
# For this purpose, the module-level "ET" symbol is temporarily # For this purpose, the module-level "ET" symbol is temporarily
# monkey-patched when running the "test_xml_etree_c" test suite. # monkey-patched when running the "test_xml_etree_c" test suite.
import copy
import html import html
import io import io
import operator import operator
...@@ -2082,6 +2083,19 @@ class ElementIterTest(unittest.TestCase): ...@@ -2082,6 +2083,19 @@ class ElementIterTest(unittest.TestCase):
self.assertEqual(self._ilist(doc), all_tags) self.assertEqual(self._ilist(doc), all_tags)
self.assertEqual(self._ilist(doc, '*'), all_tags) self.assertEqual(self._ilist(doc, '*'), all_tags)
def test_copy(self):
a = ET.Element('a')
it = a.iter()
with self.assertRaises(TypeError):
copy.copy(it)
def test_pickle(self):
a = ET.Element('a')
it = a.iter()
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
with self.assertRaises((TypeError, pickle.PicklingError)):
pickle.dumps(it, proto)
class TreeBuilderTest(unittest.TestCase): class TreeBuilderTest(unittest.TestCase):
sample1 = ('<!DOCTYPE html PUBLIC' sample1 = ('<!DOCTYPE html PUBLIC'
......
import unittest import unittest
from test import support from test import support
import binascii import binascii
import pickle
import random import random
import sys import sys
from test.support import bigmemtest, _1G, _4G from test.support import bigmemtest, _1G, _4G
...@@ -600,6 +601,16 @@ class CompressObjectTestCase(BaseCompressTestCase, unittest.TestCase): ...@@ -600,6 +601,16 @@ class CompressObjectTestCase(BaseCompressTestCase, unittest.TestCase):
d.flush() d.flush()
self.assertRaises(ValueError, d.copy) self.assertRaises(ValueError, d.copy)
def test_compresspickle(self):
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
with self.assertRaises((TypeError, pickle.PicklingError)):
pickle.dumps(zlib.compressobj(zlib.Z_BEST_COMPRESSION), proto)
def test_decompresspickle(self):
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
with self.assertRaises((TypeError, pickle.PicklingError)):
pickle.dumps(zlib.decompressobj(), proto)
# Memory use of the following functions takes into account overallocation # Memory use of the following functions takes into account overallocation
@bigmemtest(size=_1G + 1024 * 1024, memuse=3) @bigmemtest(size=_1G + 1024 * 1024, memuse=3)
......
...@@ -10,6 +10,9 @@ Release date: tba ...@@ -10,6 +10,9 @@ Release date: tba
Core and Builtins Core and Builtins
----------------- -----------------
- Issue #22995: Default implementation of __reduce__ and __reduce_ex__ now
rejects builtin types with not defined __new__.
- Issue #24802: Avoid buffer overreads when int(), float(), compile(), exec() - Issue #24802: Avoid buffer overreads when int(), float(), compile(), exec()
and eval() are passed bytes-like objects. These objects are not and eval() are passed bytes-like objects. These objects are not
necessarily terminated by a null byte, but the functions assumed they were. necessarily terminated by a null byte, but the functions assumed they were.
......
...@@ -3980,6 +3980,12 @@ reduce_4(PyObject *obj) ...@@ -3980,6 +3980,12 @@ reduce_4(PyObject *obj)
PyObject *result; PyObject *result;
_Py_IDENTIFIER(__newobj_ex__); _Py_IDENTIFIER(__newobj_ex__);
if (Py_TYPE(obj)->tp_new == NULL) {
PyErr_Format(PyExc_TypeError,
"can't pickle %s objects",
Py_TYPE(obj)->tp_name);
return NULL;
}
if (_PyObject_GetNewArguments(obj, &args, &kwargs) < 0) { if (_PyObject_GetNewArguments(obj, &args, &kwargs) < 0) {
return NULL; return NULL;
} }
...@@ -4046,6 +4052,12 @@ reduce_2(PyObject *obj) ...@@ -4046,6 +4052,12 @@ reduce_2(PyObject *obj)
Py_ssize_t i, n; Py_ssize_t i, n;
_Py_IDENTIFIER(__newobj__); _Py_IDENTIFIER(__newobj__);
if (Py_TYPE(obj)->tp_new == NULL) {
PyErr_Format(PyExc_TypeError,
"can't pickle %s objects",
Py_TYPE(obj)->tp_name);
return NULL;
}
if (_PyObject_GetNewArguments(obj, &args, &kwargs) < 0) { if (_PyObject_GetNewArguments(obj, &args, &kwargs) < 0) {
return NULL; return NULL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment