]> granicus.if.org Git - python/commitdiff
Make AST nodes pickleable.
authorGeorg Brandl <georg@python.org>
Sun, 30 Mar 2008 20:20:39 +0000 (20:20 +0000)
committerGeorg Brandl <georg@python.org>
Sun, 30 Mar 2008 20:20:39 +0000 (20:20 +0000)
Lib/test/test_ast.py
Parser/asdl_c.py
Python/Python-ast.c

index e068b0a1145f6554437a73ddd516e3c7f8d13188..9d2bd664a4271460a453fc62d02526c42aa46cd6 100644 (file)
@@ -166,6 +166,20 @@ class AST_Tests(unittest.TestCase):
         # this used to fail because Sub._fields was None
         x = _ast.Sub()
 
+    def test_pickling(self):
+        import pickle
+        mods = [pickle]
+        try:
+            import cPickle
+            mods.append(cPickle)
+        except ImportError:
+            pass
+        protocols = [0, 1, 2]
+        for mod in mods:
+            for protocol in protocols:
+                for ast in (compile(i, "?", "exec", 0x400) for i in exec_tests):
+                    ast2 = mod.loads(mod.dumps(ast, protocol))
+                    self.assertEquals(to_tuple(ast2), to_tuple(ast))
 
 def test_main():
     test_support.run_unittest(AST_Tests)
index 29e2547595ca87f7e3f4aac06393ef08cf33e886..7e12ea66d05676543ba8e394b8baaa13853209d0 100755 (executable)
@@ -629,9 +629,34 @@ ast_type_init(PyObject *self, PyObject *args, PyObject *kw)
     return res;
 }
 
+/* Pickling support */
+static PyObject *
+ast_type_reduce(PyObject *self, PyObject *unused)
+{
+    PyObject *res;
+    PyObject *dict = PyObject_GetAttrString(self, "__dict__");
+    if (dict == NULL) {
+        if (PyErr_ExceptionMatches(PyExc_AttributeError))
+            PyErr_Clear();
+        else
+            return NULL;
+    }
+    if (dict) {
+        res = Py_BuildValue("O()O", Py_TYPE(self), dict);
+        Py_DECREF(dict);
+        return res;
+    }
+    return Py_BuildValue("O()", Py_TYPE(self));
+}
+
+static PyMethodDef ast_type_methods[] = {
+    {"__reduce__", ast_type_reduce, METH_NOARGS, NULL},
+    {NULL}
+};
+
 static PyTypeObject AST_type = {
     PyVarObject_HEAD_INIT(&PyType_Type, 0)
-    "AST",
+    "_ast.AST",
     sizeof(PyObject),
     0,
     0,                       /* tp_dealloc */
@@ -657,7 +682,7 @@ static PyTypeObject AST_type = {
     0,                       /* tp_weaklistoffset */
     0,                       /* tp_iter */
     0,                       /* tp_iternext */
-    0,                       /* tp_methods */
+    ast_type_methods,        /* tp_methods */
     0,                       /* tp_members */
     0,                       /* tp_getset */
     0,                       /* tp_base */
index ba310e60890232e15678e1a31d9eabdf3a4f95dc..f958145a23317903b2cdab062b85c47b4fb368b5 100644 (file)
@@ -420,9 +420,34 @@ ast_type_init(PyObject *self, PyObject *args, PyObject *kw)
     return res;
 }
 
+/* Pickling support */
+static PyObject *
+ast_type_reduce(PyObject *self, PyObject *unused)
+{
+    PyObject *res;
+    PyObject *dict = PyObject_GetAttrString(self, "__dict__");
+    if (dict == NULL) {
+        if (PyErr_ExceptionMatches(PyExc_AttributeError))
+            PyErr_Clear();
+        else
+            return NULL;
+    }
+    if (dict) {
+        res = Py_BuildValue("O()O", Py_TYPE(self), dict);
+        Py_DECREF(dict);
+        return res;
+    }
+    return Py_BuildValue("O()", Py_TYPE(self));
+}
+
+static PyMethodDef ast_type_methods[] = {
+    {"__reduce__", ast_type_reduce, METH_NOARGS, NULL},
+    {NULL}
+};
+
 static PyTypeObject AST_type = {
     PyVarObject_HEAD_INIT(&PyType_Type, 0)
-    "AST",
+    "_ast.AST",
     sizeof(PyObject),
     0,
     0,                       /* tp_dealloc */
@@ -448,7 +473,7 @@ static PyTypeObject AST_type = {
     0,                       /* tp_weaklistoffset */
     0,                       /* tp_iter */
     0,                       /* tp_iternext */
-    0,                       /* tp_methods */
+    ast_type_methods,        /* tp_methods */
     0,                       /* tp_members */
     0,                       /* tp_getset */
     0,                       /* tp_base */