summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Behnel <stefan_ml@behnel.de>2016-01-16 11:06:04 +0100
committerStefan Behnel <stefan_ml@behnel.de>2016-01-16 11:10:20 +0100
commit918cc8a88070c8605e69dd4757a1764ba652ccf3 (patch)
treec7958989135b6e7bdec25218310ec0c1fa785c81
parent4be4cb27d2925fc4842a5808469845418a511eac (diff)
downloadcython-918cc8a88070c8605e69dd4757a1764ba652ccf3.tar.gz
repair deep-copying (and pickling) of the control flow state in compiled Cython (extension type instances lost their state)
-rw-r--r--Cython/Compiler/FlowControl.py8
-rw-r--r--Cython/Compiler/Tests/TestFlowControl.py68
2 files changed, 76 insertions, 0 deletions
diff --git a/Cython/Compiler/FlowControl.py b/Cython/Compiler/FlowControl.py
index b4a935625..b859e1bc0 100644
--- a/Cython/Compiler/FlowControl.py
+++ b/Cython/Compiler/FlowControl.py
@@ -341,6 +341,14 @@ class NameAssignment(object):
return self.entry.type
return self.inferred_type
+ def __getstate__(self):
+ return (self.lhs, self.rhs, self.entry, self.pos,
+ self.refs, self.is_arg, self.is_deletion, self.inferred_type)
+
+ def __setstate__(self, state):
+ (self.lhs, self.rhs, self.entry, self.pos,
+ self.refs, self.is_arg, self.is_deletion, self.inferred_type) = state
+
class StaticAssignment(NameAssignment):
"""Initialised at declaration time, e.g. stack allocation."""
diff --git a/Cython/Compiler/Tests/TestFlowControl.py b/Cython/Compiler/Tests/TestFlowControl.py
new file mode 100644
index 000000000..443551ab8
--- /dev/null
+++ b/Cython/Compiler/Tests/TestFlowControl.py
@@ -0,0 +1,68 @@
+
+from __future__ import absolute_import
+
+from copy import deepcopy
+from unittest import TestCase
+
+from Cython.Compiler.FlowControl import (
+ NameAssignment, StaticAssignment, Argument, NameDeletion)
+
+
+class FakeType(object):
+ is_pyobject = True
+
+
+class FakeNode(object):
+ pos = ('filename.pyx', 1, 2)
+ cf_state = None
+ type = FakeType()
+
+ def infer_type(self, scope):
+ return self.type
+
+
+class FakeEntry(object):
+ type = FakeType()
+
+
+class TestGraph(TestCase):
+ def test_deepcopy(self):
+ lhs, rhs = FakeNode(), FakeNode()
+ entry = FakeEntry()
+ entry.pos = lhs.pos
+
+ name_ass = NameAssignment(lhs, rhs, entry)
+ ass = deepcopy(name_ass)
+ self.assertTrue(ass.lhs)
+ self.assertTrue(ass.rhs)
+ self.assertTrue(ass.entry)
+ self.assertEqual(ass.pos, name_ass.pos)
+ self.assertFalse(ass.is_arg)
+ self.assertFalse(ass.is_deletion)
+
+ static_ass = StaticAssignment(entry)
+ ass = deepcopy(static_ass)
+ self.assertTrue(ass.lhs)
+ self.assertTrue(ass.rhs)
+ self.assertTrue(ass.entry)
+ self.assertEqual(ass.pos, static_ass.pos)
+ self.assertFalse(ass.is_arg)
+ self.assertFalse(ass.is_deletion)
+
+ arg_ass = Argument(lhs, rhs, entry)
+ ass = deepcopy(arg_ass)
+ self.assertTrue(ass.lhs)
+ self.assertTrue(ass.rhs)
+ self.assertTrue(ass.entry)
+ self.assertEqual(ass.pos, arg_ass.pos)
+ self.assertTrue(ass.is_arg)
+ self.assertFalse(ass.is_deletion)
+
+ name_del = NameDeletion(lhs, entry)
+ ass = deepcopy(name_del)
+ self.assertTrue(ass.lhs)
+ self.assertTrue(ass.rhs)
+ self.assertTrue(ass.entry)
+ self.assertEqual(ass.pos, name_del.pos)
+ self.assertFalse(ass.is_arg)
+ self.assertTrue(ass.is_deletion)