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
_align_function_definitions,
ConstantFolding(),
FlattenInListTransform(),
+ WithTransform(self),
DecoratorTransform(self),
AnalyseDeclarationsTransform(self),
AutoTestDictTransform(self),
"""
Represents a Python with statement.
- Implemented as follows:
+ Implemented by the WithTransform as follows:
MGR = EXPR
EXIT = MGR.__exit__
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)
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):