Commit fa53d215 authored by Alexandre Vassalotti's avatar Alexandre Vassalotti

Issue #6477: Merge with 3.3.

parents ea29612b eb2bce5d
......@@ -829,6 +829,9 @@ they can have object code that is not dependent on Python compilation flags.
PyAPI_FUNC(void) Py_IncRef(PyObject *);
PyAPI_FUNC(void) Py_DecRef(PyObject *);
PyAPI_DATA(PyTypeObject) PyNone_Type;
PyAPI_DATA(PyTypeObject) PyNotImplemented_Type;
/*
_Py_NoneStruct is an object of undefined type which can be used in contexts
where NULL (nil) is not suitable (since NULL often means 'error').
......
......@@ -954,8 +954,17 @@ class _Pickler:
self.memoize(obj)
def save_type(self, obj):
if obj is type(None):
return self.save_reduce(type, (None,), obj=obj)
elif obj is type(NotImplemented):
return self.save_reduce(type, (NotImplemented,), obj=obj)
elif obj is type(...):
return self.save_reduce(type, (...,), obj=obj)
return self.save_global(obj)
dispatch[FunctionType] = save_global
dispatch[type] = save_global
dispatch[type] = save_type
# Unpickling machinery
......
......@@ -804,6 +804,15 @@ class AbstractPickleTests(unittest.TestCase):
u = self.loads(s)
self.assertIs(NotImplemented, u)
def test_singleton_types(self):
# Issue #6477: Test that types of built-in singletons can be pickled.
singletons = [None, ..., NotImplemented]
for singleton in singletons:
for proto in protocols:
s = self.dumps(type(singleton), proto)
u = self.loads(s)
self.assertIs(type(singleton), u)
# Tests for protocol 2
def test_proto(self):
......
......@@ -33,6 +33,9 @@ Library
- Fixed _pickle.Unpickler to not fail when loading empty strings as
persistent IDs.
- Issue #6477: Added support for pickling the types of built-in singletons
(i.e., Ellipsis, NotImplemented, None).
- ssl.create_default_context() sets OP_NO_COMPRESSION to prevent CRIME.
- Issue #19802: Add socket.SO_PRIORITY.
......
......@@ -3287,6 +3287,36 @@ save_global(PicklerObject *self, PyObject *obj, PyObject *name)
return status;
}
static int
save_singleton_type(PicklerObject *self, PyObject *obj, PyObject *singleton)
{
PyObject *reduce_value;
int status;
reduce_value = Py_BuildValue("O(O)", &PyType_Type, singleton);
if (reduce_value == NULL) {
return -1;
}
status = save_reduce(self, reduce_value, obj);
Py_DECREF(reduce_value);
return status;
}
static int
save_type(PicklerObject *self, PyObject *obj)
{
if (obj == (PyObject *)&PyNone_Type) {
return save_singleton_type(self, obj, Py_None);
}
else if (obj == (PyObject *)&PyEllipsis_Type) {
return save_singleton_type(self, obj, Py_Ellipsis);
}
else if (obj == (PyObject *)&PyNotImplemented_Type) {
return save_singleton_type(self, obj, Py_NotImplemented);
}
return save_global(self, obj, NULL);
}
static int
save_pers(PicklerObject *self, PyObject *obj, PyObject *func)
{
......@@ -3696,7 +3726,7 @@ save(PicklerObject *self, PyObject *obj, int pers_save)
goto done;
}
else if (type == &PyType_Type) {
status = save_global(self, obj, NULL);
status = save_type(self, obj);
goto done;
}
else if (type == &PyFunction_Type) {
......
......@@ -1409,7 +1409,7 @@ static PyNumberMethods none_as_number = {
0, /* nb_index */
};
static PyTypeObject PyNone_Type = {
PyTypeObject PyNone_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"NoneType",
0,
......@@ -1494,7 +1494,7 @@ notimplemented_dealloc(PyObject* ignore)
Py_FatalError("deallocating NotImplemented");
}
static PyTypeObject PyNotImplemented_Type = {
PyTypeObject PyNotImplemented_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"NotImplementedType",
0,
......
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