From 8fb74a35da34cf33704f30f97cf962905b2a643a Mon Sep 17 00:00:00 2001 From: Stefan Krah Date: Tue, 29 Apr 2014 18:24:50 +0200 Subject: [PATCH] Issue #21374: Fix pickling of DecimalTuple. --- Lib/test/test_decimal.py | 17 +++++++++++++++++ Modules/_decimal/_decimal.c | 13 +++++++++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index 40313475fb9..4b279071dfd 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -2431,6 +2431,23 @@ class PythonAPItests(unittest.TestCase): self.assertIsInstance(r, C.Decimal) self.assertEqual(r, x) + x = C.Decimal('-3.123e81723').as_tuple() + y = P.Decimal('-3.123e81723').as_tuple() + + sys.modules['decimal'] = C + sx = pickle.dumps(x) + sys.modules['decimal'] = P + r = pickle.loads(sx) + self.assertIsInstance(r, P.DecimalTuple) + self.assertEqual(r, y) + + sys.modules['decimal'] = P + sy = pickle.dumps(y) + sys.modules['decimal'] = C + r = pickle.loads(sy) + self.assertIsInstance(r, C.DecimalTuple) + self.assertEqual(r, x) + sys.modules['decimal'] = savedecimal def test_int(self): diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index ea5253efb67..8be9be64896 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -3542,7 +3542,7 @@ PyDec_Round(PyObject *dec, PyObject *args) } } -static PyObject *DecimalTuple = NULL; +static PyTypeObject *DecimalTuple = NULL; /* Return the DecimalTuple representation of a PyDecObject. */ static PyObject * PyDec_AsTuple(PyObject *dec, PyObject *dummy UNUSED) @@ -3625,7 +3625,7 @@ PyDec_AsTuple(PyObject *dec, PyObject *dummy UNUSED) } } - result = PyObject_CallFunctionObjArgs(DecimalTuple, + result = PyObject_CallFunctionObjArgs((PyObject *)DecimalTuple, sign, coeff, expt, NULL); out: @@ -5562,9 +5562,14 @@ PyInit__decimal(void) /* DecimalTuple */ ASSIGN_PTR(collections, PyImport_ImportModule("collections")); - ASSIGN_PTR(DecimalTuple, PyObject_CallMethod(collections, + ASSIGN_PTR(DecimalTuple, (PyTypeObject *)PyObject_CallMethod(collections, "namedtuple", "(ss)", "DecimalTuple", "sign digits exponent")); + + ASSIGN_PTR(obj, PyUnicode_FromString("decimal")); + CHECK_INT(PyDict_SetItemString(DecimalTuple->tp_dict, "__module__", obj)); + Py_CLEAR(obj); + /* MutableMapping */ ASSIGN_PTR(MutableMapping, PyObject_GetAttrString(collections, "MutableMapping")); @@ -5591,7 +5596,7 @@ PyInit__decimal(void) CHECK_INT(PyModule_AddObject(m, "Context", (PyObject *)&PyDecContext_Type)); Py_INCREF(DecimalTuple); - CHECK_INT(PyModule_AddObject(m, "DecimalTuple", DecimalTuple)); + CHECK_INT(PyModule_AddObject(m, "DecimalTuple", (PyObject *)DecimalTuple)); /* Create top level exception */