From: Raymond Hettinger <python@rcn.com>
Date: Tue, 9 Nov 2004 07:25:31 +0000 (+0000)
Subject: SF 1062353:  set pickling problems
X-Git-Tag: v2.4c1~57
X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=15056a5202c89846d75006d66541d5a634ac79b5;p=python

SF 1062353:  set pickling problems

Support automatic pickling of dictionaries in instance of set subclasses.
---

diff --git a/Lib/test/test_set.py b/Lib/test/test_set.py
index aab0c5782c..900d8e42c1 100644
--- a/Lib/test/test_set.py
+++ b/Lib/test/test_set.py
@@ -175,9 +175,15 @@ class TestJointOps(unittest.TestCase):
         self.failIf(set('cbs').issuperset('a'))
 
     def test_pickling(self):
-        p = pickle.dumps(self.s)
-        dup = pickle.loads(p)
-        self.assertEqual(self.s, dup, "%s != %s" % (self.s, dup))
+        for i in (0, 1, 2):
+            p = pickle.dumps(self.s, i)
+            dup = pickle.loads(p)
+            self.assertEqual(self.s, dup, "%s != %s" % (self.s, dup))
+            if type(self.s) not in (set, frozenset):
+                self.s.x = 10
+                p = pickle.dumps(self.s)
+                dup = pickle.loads(p)
+                self.assertEqual(self.s.x, dup.x)
 
     def test_deepcopy(self):
         class Tracer:
diff --git a/Objects/setobject.c b/Objects/setobject.c
index d57217cba3..8ef671e3af 100644
--- a/Objects/setobject.c
+++ b/Objects/setobject.c
@@ -844,7 +844,7 @@ PyDoc_STRVAR(pop_doc, "Remove and return an arbitrary set element.");
 static PyObject *
 set_reduce(PySetObject *so)
 {
-	PyObject *keys=NULL, *args=NULL, *result=NULL;
+	PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL;
 
 	keys = PyDict_Keys(so->data);
 	if (keys == NULL)
@@ -852,10 +852,17 @@ set_reduce(PySetObject *so)
 	args = PyTuple_Pack(1, keys);
 	if (args == NULL)
 		goto done;
-	result = PyTuple_Pack(2, so->ob_type, args);
+	dict = PyObject_GetAttrString((PyObject *)so, "__dict__");
+	if (dict == NULL) {
+		PyErr_Clear();
+		dict = Py_None;
+		Py_INCREF(dict);
+	}
+	result = PyTuple_Pack(3, so->ob_type, args, dict);
 done:
 	Py_XDECREF(args);
 	Py_XDECREF(keys);
+	Py_XDECREF(dict);
 	return result;
 }