]> granicus.if.org Git - python/commitdiff
bpo-29914: Fix default implementations of __reduce__ and __reduce_ex__(). (#843)
authorSerhiy Storchaka <storchaka@gmail.com>
Sat, 8 Apr 2017 06:52:59 +0000 (09:52 +0300)
committerGitHub <noreply@github.com>
Sat, 8 Apr 2017 06:52:59 +0000 (09:52 +0300)
object.__reduce__() no longer takes arguments, object.__reduce_ex__() now
requires one argument.

Lib/test/test_descr.py
Misc/NEWS
Objects/clinic/typeobject.c.h
Objects/typeobject.c

index 92553e3573be44a50192ec753f4f233b4cdc20fc..ced25f3fc4424400063d90aa66cad43df07b2559 100644 (file)
@@ -5236,7 +5236,20 @@ class PicklingTests(unittest.TestCase):
 
         import copyreg
         expected = (copyreg.__newobj__, (A,), (None, {'spam': 42}), None, None)
-        self.assertEqual(A().__reduce__(2), expected)  # Shouldn't crash
+        self.assertEqual(A().__reduce_ex__(2), expected)  # Shouldn't crash
+
+    def test_object_reduce(self):
+        # Issue #29914
+        # __reduce__() takes no arguments
+        object().__reduce__()
+        with self.assertRaises(TypeError):
+            object().__reduce__(0)
+        # __reduce_ex__() takes one integer argument
+        object().__reduce_ex__(0)
+        with self.assertRaises(TypeError):
+            object().__reduce_ex__()
+        with self.assertRaises(TypeError):
+            object().__reduce_ex__(None)
 
 
 class SharedKeyTests(unittest.TestCase):
index 396ada182e197b5bde7378bb1eb8fc1e7cbc42f7..3caa1eb6e08d4df86a0e28a9a2d18a24ab5af479 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,10 @@ What's New in Python 3.7.0 alpha 1?
 Core and Builtins
 -----------------
 
+- bpo-29914: Fixed default implementations of __reduce__ and __reduce_ex__().
+  object.__reduce__() no longer takes arguments, object.__reduce_ex__() now
+  requires one argument.
+
 - bpo-29949: Fix memory usage regression of set and frozenset object.
 
 - bpo-29935: Fixed error messages in the index() method of tuple, list and deque
index 1b19ccf061510f3f7fbe67fcc258f55a149367f3..2760065ef33f7fe30c6680553a7a9dfa443b4a58 100644 (file)
@@ -131,61 +131,42 @@ type___sizeof__(PyTypeObject *self, PyObject *Py_UNUSED(ignored))
 }
 
 PyDoc_STRVAR(object___reduce____doc__,
-"__reduce__($self, protocol=0, /)\n"
+"__reduce__($self, /)\n"
 "--\n"
 "\n"
 "Helper for pickle.");
 
 #define OBJECT___REDUCE___METHODDEF    \
-    {"__reduce__", (PyCFunction)object___reduce__, METH_FASTCALL, object___reduce____doc__},
+    {"__reduce__", (PyCFunction)object___reduce__, METH_NOARGS, object___reduce____doc__},
 
 static PyObject *
-object___reduce___impl(PyObject *self, int protocol);
+object___reduce___impl(PyObject *self);
 
 static PyObject *
-object___reduce__(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
+object___reduce__(PyObject *self, PyObject *Py_UNUSED(ignored))
 {
-    PyObject *return_value = NULL;
-    int protocol = 0;
-
-    if (!_PyArg_ParseStack(args, nargs, "|i:__reduce__",
-        &protocol)) {
-        goto exit;
-    }
-
-    if (!_PyArg_NoStackKeywords("__reduce__", kwnames)) {
-        goto exit;
-    }
-    return_value = object___reduce___impl(self, protocol);
-
-exit:
-    return return_value;
+    return object___reduce___impl(self);
 }
 
 PyDoc_STRVAR(object___reduce_ex____doc__,
-"__reduce_ex__($self, protocol=0, /)\n"
+"__reduce_ex__($self, protocol, /)\n"
 "--\n"
 "\n"
 "Helper for pickle.");
 
 #define OBJECT___REDUCE_EX___METHODDEF    \
-    {"__reduce_ex__", (PyCFunction)object___reduce_ex__, METH_FASTCALL, object___reduce_ex____doc__},
+    {"__reduce_ex__", (PyCFunction)object___reduce_ex__, METH_O, object___reduce_ex____doc__},
 
 static PyObject *
 object___reduce_ex___impl(PyObject *self, int protocol);
 
 static PyObject *
-object___reduce_ex__(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
+object___reduce_ex__(PyObject *self, PyObject *arg)
 {
     PyObject *return_value = NULL;
-    int protocol = 0;
-
-    if (!_PyArg_ParseStack(args, nargs, "|i:__reduce_ex__",
-        &protocol)) {
-        goto exit;
-    }
+    int protocol;
 
-    if (!_PyArg_NoStackKeywords("__reduce_ex__", kwnames)) {
+    if (!PyArg_Parse(arg, "i:__reduce_ex__", &protocol)) {
         goto exit;
     }
     return_value = object___reduce_ex___impl(self, protocol);
@@ -256,4 +237,4 @@ object___dir__(PyObject *self, PyObject *Py_UNUSED(ignored))
 {
     return object___dir___impl(self);
 }
-/*[clinic end generated code: output=ce354e436e2360a0 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=8c4c856859564eaa input=a9049054013a1b77]*/
index 4a9949e4022690050649589c3b19f4cb29980139..369c72f81d32ca28cf04ab7e23f9d8fe8cc232bc 100644 (file)
@@ -4393,23 +4393,20 @@ _common_reduce(PyObject *self, int proto)
 /*[clinic input]
 object.__reduce__
 
-  protocol: int = 0
-  /
-
 Helper for pickle.
 [clinic start generated code]*/
 
 static PyObject *
-object___reduce___impl(PyObject *self, int protocol)
-/*[clinic end generated code: output=5572e699c467dd5b input=227f37ed68bd938a]*/
+object___reduce___impl(PyObject *self)
+/*[clinic end generated code: output=d4ca691f891c6e2f input=11562e663947e18b]*/
 {
-    return _common_reduce(self, protocol);
+    return _common_reduce(self, 0);
 }
 
 /*[clinic input]
 object.__reduce_ex__
 
-  protocol: int = 0
+  protocol: int
   /
 
 Helper for pickle.
@@ -4417,7 +4414,7 @@ Helper for pickle.
 
 static PyObject *
 object___reduce_ex___impl(PyObject *self, int protocol)
-/*[clinic end generated code: output=2e157766f6b50094 input=8dd6a9602a12749e]*/
+/*[clinic end generated code: output=2e157766f6b50094 input=f326b43fb8a4c5ff]*/
 {
     static PyObject *objreduce;
     PyObject *reduce, *res;