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
 
     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
         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(),
             _align_function_definitions,
             ConstantFolding(),
             FlattenInListTransform(),
+            WithTransform(self),
             DecoratorTransform(self),
             AnalyseDeclarationsTransform(self),
             AutoTestDictTransform(self),
             DecoratorTransform(self),
             AnalyseDeclarationsTransform(self),
             AutoTestDictTransform(self),
index 8007d83a98d9afc553f36f9d0cba01672d20a1ab..006133c4d4f05db980490228d7d8bf1ae4eaf5f1 100644 (file)
@@ -4835,7 +4835,7 @@ class WithStatNode(StatNode):
     """
     Represents a Python with statement.
 
     """
     Represents a Python with statement.
 
-    Implemented as follows:
+    Implemented by the WithTransform as follows:
 
         MGR = EXPR
         EXIT = MGR.__exit__
 
         MGR = EXPR
         EXIT = MGR.__exit__
@@ -4855,61 +4855,13 @@ class WithStatNode(StatNode):
             MGR = EXIT = VALUE = None
     """
     #  manager          The with statement manager object
             MGR = EXIT = VALUE = None
     """
     #  manager          The with statement manager object
+    #  target           ExprNode  the target lhs of the __enter__() call
     #  body             StatNode
 
     #  body             StatNode
 
-    child_attrs = ["manager", "body"]
+    child_attrs = ["manager", "target", "body"]
 
     has_target = False
 
 
     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)
     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)
 
             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):
 
 
 class DecoratorTransform(CythonTransform, SkipDeclarations):