def parse_and(self): lineno = self.stream.current.lineno left = self.parse_not() while self.stream.skip_if('name:and'): right = self.parse_not() left = nodes.And(left, right, lineno=lineno) lineno = self.stream.current.lineno return left
def parse(self, parser): # Create a normal With node first # Borrowing the codes from parser.py, # the only difference is the end tag is `endrequired` # instead of `endwith` with_node = nodes.With(lineno=next(parser.stream).lineno) targets = [] values = [] while parser.stream.current.type != 'block_end': if targets: parser.stream.expect('comma') target = parser.parse_assign_target() target.set_ctx('param') targets.append(target) parser.stream.expect('assign') values.append(parser.parse_expression()) with_node.targets = targets with_node.values = values with_node.body = parser.parse_statements(('name:endrequired', ), drop_needle=True) # Manually create a If node if_node = nodes.If() # If only one variable is required, assigned that variable to test if it is empty if len(values) == 1: test = values[0] else: # If more than one variables are required, concat them into a And node test = nodes.And(left=values[0], right=values[1]) for i in range(2, len(values)): test = nodes.And(left=test, right=values[i]) if_node.test = test # Assign with_node as the body of the if_node, to nest them if_node.body = [with_node] # set other fields to empty list. for _f in nodes.If: if getattr(if_node, _f) is None: setattr(if_node, _f, []) return if_node
def parse(self, parser): lineno = next(parser.stream).lineno # Get the block selection from the tag argument. block_selection = parser.parse_expression() # Make "Name" node for "For" node target. block_name = nodes.Name('_ext_ob_blknm', 'store') # For each block, add an "If" node checking if it matches the target. # Also record the original "default" ordering of the blocks. blocks = [] block_names = [] for node in parser.parse_statements(['name:endorderblocks'], drop_needle=True): if isinstance(node, nodes.Block): blocks.append(nodes.If( nodes.Compare( block_name, [nodes.Operand('eq', nodes.Const(node.name))]), [node], [])) block_names.append(node.name) # Make a "For" node iterating over the given block selection. If the # block selection is undefined or None then use the original ordering. return nodes.For( block_name, nodes.CondExpr( nodes.And( nodes.Test(block_selection, 'defined', [], [], None, None), nodes.Not( nodes.Test(block_selection, 'none', [], [], None, None)), ), block_selection, nodes.Tuple([nodes.Const(x) for x in block_names], 'store')), blocks, [], None, False)