move 'with' statement implementation back into WithTransform to fix 'with' statement...
authorStefan Behnel <scoder@users.berlios.de>
Sun, 24 Apr 2011 23:09:26 +0000 (01:09 +0200)
committerStefan Behnel <scoder@users.berlios.de>
Sun, 24 Apr 2011 23:09:26 +0000 (01:09 +0200)
Cython/Compiler/Main.py
Cython/Compiler/Nodes.py
Cython/Compiler/ParseTreeTransforms.py

index 34d8b22f922b05c422e242044731f15c289d7820..fb8d6fcb02d5d9ffdc7fea9b4774e763164ac3e4 100644 (file)
@@ -102,7 +102,7 @@ class Context(object):
 
     def create_pipeline(self, pxd, py=False):
         from Visitor import PrintTree
-        from ParseTreeTransforms import NormalizeTree, PostParse, PxdPostParse
+        from ParseTreeTransforms import WithTransform, NormalizeTree, PostParse, PxdPostParse
         from ParseTreeTransforms import AnalyseDeclarationsTransform, AnalyseExpressionsTransform
         from ParseTreeTransforms import CreateClosureClasses, MarkClosureVisitor, DecoratorTransform
         from ParseTreeTransforms import InterpretCompilerDirectives, TransformBuiltinMethods
@@ -139,6 +139,7 @@ class Context(object):
             _align_function_definitions,
             ConstantFolding(),
             FlattenInListTransform(),
+            WithTransform(self),
             DecoratorTransform(self),
             AnalyseDeclarationsTransform(self),
             AutoTestDictTransform(self),
index 8007d83a98d9afc553f36f9d0cba01672d20a1ab..006133c4d4f05db980490228d7d8bf1ae4eaf5f1 100644 (file)
@@ -4835,7 +4835,7 @@ class WithStatNode(StatNode):
     """
     Represents a Python with statement.
 
-    Implemented as follows:
+    Implemented by the WithTransform as follows:
 
         MGR = EXPR
         EXIT = MGR.__exit__
@@ -4855,61 +4855,13 @@ class WithStatNode(StatNode):
             MGR = EXIT = VALUE = None
     """
     #  manager          The with statement manager object
+    #  target           ExprNode  the target lhs of the __enter__() call
     #  body             StatNode
 
-    child_attrs = ["manager", "body"]
+    child_attrs = ["manager", "target", "body"]
 
     has_target = False
 
-    def __init__(self, pos, manager, target, body):
-        StatNode.__init__(self, pos, manager = manager)
-
-        import ExprNodes
-        self.target_temp = ExprNodes.TempNode(pos, type=py_object_type)
-        if target is not None:
-            self.has_target = True
-            body = StatListNode(
-                pos, stats = [
-                    WithTargetAssignmentStatNode(
-                        pos, lhs = target, rhs = self.target_temp),
-                    body
-                    ])
-
-        import UtilNodes
-        excinfo_target = UtilNodes.ResultRefNode(
-            pos=pos, type=Builtin.tuple_type, may_hold_none=False)
-        except_clause = ExceptClauseNode(
-            pos, body = IfStatNode(
-                pos, if_clauses = [
-                    IfClauseNode(
-                        pos, condition = ExprNodes.NotNode(
-                            pos, operand = ExprNodes.WithExitCallNode(
-                                pos, with_stat = self,
-                                args = excinfo_target)),
-                        body = ReraiseStatNode(pos),
-                        ),
-                    ],
-                else_clause = None),
-            pattern = None,
-            target = None,
-            excinfo_target = excinfo_target,
-            )
-
-        self.body = TryFinallyStatNode(
-            pos, body = TryExceptStatNode(
-                pos, body = body,
-                except_clauses = [except_clause],
-                else_clause = None,
-                ),
-            finally_clause = ExprStatNode(
-                pos, expr = ExprNodes.WithExitCallNode(
-                    pos, with_stat = self,
-                    args = ExprNodes.TupleNode(
-                        pos, args = [ExprNodes.NoneNode(pos) for _ in range(3)]
-                        ))),
-            handle_error_case = False,
-            )
-
     def analyse_declarations(self, env):
         self.manager.analyse_declarations(env)
         self.body.analyse_declarations(env)
index 8283094a8530934d0b49fb30f3249a51e01907bb..00de70a359adb9046849b946e4e9a49ac91f7a53 100644 (file)
@@ -897,6 +897,61 @@ class InterpretCompilerDirectives(CythonTransform, SkipDeclarations):
             return self.visit_with_directives(node.body, directive_dict)
         return self.visit_Node(node)
 
+class WithTransform(CythonTransform, SkipDeclarations):
+    def visit_WithStatNode(self, node):
+        self.visitchildren(node, 'body')
+        pos = node.pos
+        body, target, manager = node.body, node.target, node.manager
+        node.target_temp = ExprNodes.TempNode(pos, type=PyrexTypes.py_object_type)
+        if target is not None:
+            node.has_target = True
+            body = Nodes.StatListNode(
+                pos, stats = [
+                    Nodes.WithTargetAssignmentStatNode(
+                        pos, lhs = target, rhs = node.target_temp),
+                    body
+                    ])
+            node.target = None
+
+        excinfo_target = ResultRefNode(
+            pos=pos, type=Builtin.tuple_type, may_hold_none=False)
+        except_clause = Nodes.ExceptClauseNode(
+            pos, body = Nodes.IfStatNode(
+                pos, if_clauses = [
+                    Nodes.IfClauseNode(
+                        pos, condition = ExprNodes.NotNode(
+                            pos, operand = ExprNodes.WithExitCallNode(
+                                pos, with_stat = node,
+                                args = excinfo_target)),
+                        body = Nodes.ReraiseStatNode(pos),
+                        ),
+                    ],
+                else_clause = None),
+            pattern = None,
+            target = None,
+            excinfo_target = excinfo_target,
+            )
+
+        node.body = Nodes.TryFinallyStatNode(
+            pos, body = Nodes.TryExceptStatNode(
+                pos, body = body,
+                except_clauses = [except_clause],
+                else_clause = None,
+                ),
+            finally_clause = Nodes.ExprStatNode(
+                pos, expr = ExprNodes.WithExitCallNode(
+                    pos, with_stat = node,
+                    args = ExprNodes.TupleNode(
+                        pos, args = [ExprNodes.NoneNode(pos) for _ in range(3)]
+                        ))),
+            handle_error_case = False,
+            )
+        return node
+
+    def visit_ExprNode(self, node):
+        # With statements are never inside expressions.
+        return node
+
 
 class DecoratorTransform(CythonTransform, SkipDeclarations):