def transform(self, node, results): print_stmt = results['string'] print_stmt.prefix = '' raise_stmt = Call(Name("six.print_"), [String(print_stmt)]) raise_stmt.prefix = node.prefix print(raise_stmt) return raise_stmt
def _handle_no_args(self, node, method_name): if method_name == "getcwd": method_name = "cwd" if method_name == "listdir": return Call(Name('list'), [Call(Name('Path(".").glob'), args=[String('"*"')])], prefix=node.prefix) return Call(Name('Path.{}'.format(method_name)), prefix=node.prefix)
def _handle_buildin(self, node, method_name): if method_name == "open": arglist = node.children[1].children[1] first_arg, remaining_args = self._split_arguments(arglist) x = Call(Name("Path"), first_arg, prefix=node.prefix) x.append_child(Call(Name("open"), remaining_args, prefix=".")) return x else: raise ValueError("Method not found")
def AlmostOp(places_op, delta_op, first, second, kws): first.prefix = "" second.prefix = "" abs_op = Call(Name('abs'), [Node(syms.factor, [first, Name('-'), second])]) if kws.get('delta', None) is not None: # delta return CompOp(delta_op, abs_op, kws['delta'], {}) else: # `7` is the default in unittest.TestCase.asserAlmostEqual places = kws['places'] or Number(7) places.prefix = " " round_op = Call(Name('round'), (abs_op, Comma(), places)) return CompOp(places_op, round_op, Number(0), {})
def transform(self, node, results): if _literal_re.match(node.value): touch_import(None, u'six', node) new = node.clone() new.value = new.value[1:] new.prefix = '' node.replace(Call(Name(u'six.u', prefix=node.prefix), [new]))
def transform(self, node, results): u""" Call __builtins__.long() with the value and the base of the value. This works because 0b10 is int("10", 2), 0o10 is int("10", 8), etc. """ val = node.value base_ = base(val) if base_ == 8: assert val.strip().startswith(u"0o") or \ val.strip().startswith( u"0O"), u"Invalid format for octal literal" node.changed() node.value = u"".join((u"0", val[2:])) elif base_ == 2: assert val.startswith(u"0") and val[1] in u"bB", \ u"Invalid format for binary literal" # __builtins__.long func_name = Node(syms.power, Attr(Name(u"__builtins__"), Name(u"long"))) # ("...", 2) func_args = [ String(u"".join((u"\"", val.strip()[2:], u"\""))), Comma(), Number(2, prefix=u" ") ] new_node = Call(func_name, func_args, node.prefix) return new_node
def transform(self, node, results): if self.filename in blacklist: return elif self.filename == 'mercurial/util.py': touch_import('.', 'py3kcompat', node=node) formatstr = results['formatstr'].clone() data = results['data'].clone() formatstr.prefix = '' # remove spaces from start if isnumberremainder(formatstr, data): return # We have two possibilities: # 1- An identifier or name is passed, it is going to be a leaf, thus, we # just need to copy its value as an argument to the formatter; # 2- A tuple is explicitly passed. In this case, we're gonna explode it # to pass to the formatter # TODO: Check for normal strings. They don't need to be translated if is_tuple(data): args = [formatstr, Comma().clone()] + \ [c.clone() for c in data.children[:]] else: args = [formatstr, Comma().clone(), data] call = Call(Name('bytesformatter', prefix=' '), args) return call
def transform(self, node, results): if 'sys_import' in results: if self.sys_import is None: self.sys_import = results['sys_import'] return else: func = results['func'].clone() func.prefix = u'' register = pytree.Node(syms.power, Attr(Name(u'atexit'), Name(u'register'))) call = Call(register, [func], node.prefix) node.replace(call) if self.sys_import is None: self.warning(node, "Can't find sys import; Please add an atexit import at the top of your file.") return names = self.sys_import.children[1] if names.type == syms.dotted_as_names: names.append_child(Comma()) names.append_child(Name(u'atexit', u' ')) else: containing_stmt = self.sys_import.parent position = containing_stmt.children.index(self.sys_import) stmt_container = containing_stmt.parent new_import = pytree.Node(syms.import_name, [Name(u'import'), Name(u'atexit', u' ')]) new = pytree.Node(syms.simple_stmt, [new_import]) containing_stmt.insert_child(position + 1, Newline()) containing_stmt.insert_child(position + 2, new) return
def transform(self, node, results): if 'importname' in results: # Change the import from CONSTANT to get_constant: node = results['importname'] node.value = 'get_constant' node.changed() if 'constant' in results or 'attribute' in results: if 'attribute' in results: # Here it's used as an attribute. node = results['attribute'] else: # Here it's used standalone. node = results['constant'] # Assert that it really is standalone and not # an attribute of something else, or an # assignment etc: if not is_probably_builtin(node): return None # Now we replace the earlier constant name with the # new function call. If it was renamed on import # from 'CONSTANT' we keep the renaming else we # replace it with the new 'get_constant' name: name = node.value if name == 'CONSTANT': name = 'get_constant' node.replace(Call(Name(name), prefix=node.prefix))
def transform(self, node, results): cls = node.parent.parent.parent.parent assert cls.type == syms.classdef, ( "Internal error in the fields annotator" ) ast_node_name = cls.children[1].value ast_node = self.astnodes()[ast_node_name] ":type: langkit.compiled_types.ASTNodeType" field_name = node.parent.children[0].value field = ast_node.get_abstract_node_data_dict()[field_name] field_type_name = field.type.dsl_name # This assumes that a typerepo instance of name T is available in # the environment in which nodes are defined. type_expr = build_attr("T", field_type_name) if field.type.is_list_type: type_expr = build_attr( build_attr("T", field.type.element_type.dsl_name), "list" ) return Call(Name(" Field"), [KeywordArg(Name("type"), type_expr)])
def transform(self, node, results): assert results base = results.get("base") attr = results.get("attr") name = results.get("name") if base: if self.shadowed_next: # Omit this: # attr.replace(Name("__next__", prefix=attr.prefix)) pass else: base = [n.clone() for n in base] base[0].prefix = "" node.replace(Call(Name("next", prefix=node.prefix), base)) elif name: # Omit this: # n = Name("__next__", prefix=name.prefix) # name.replace(n) pass elif attr: # We don't do this transformation if we're assigning to "x.next". # Unfortunately, it doesn't seem possible to do this in PATTERN, # so it's being done here. if is_assign_target(node): head = results["head"] if "".join([str(n) for n in head]).strip() == '__builtin__': self.warning(node, bind_warning) return # Omit this: # attr.replace(Name("__next__")) elif "global" in results: self.warning(node, bind_warning) self.shadowed_next = True
def transform(self, node: LN, capture: Capture) -> None: if node.type == syms.simple_stmt: trust_trace_headers_value = None header_trust_handler_seen = False for prev_argument, argument in pairwise(capture["arguments"]): if argument.type == syms.argument: if argument.children[0].value == "trust_trace_headers": assert argument.children[1].value == "=" trust_trace_headers_value = argument.children[2].clone() argument.remove() if prev_argument.type == token.COMMA: prev_argument.remove() elif argument.children[0].value == "header_trust_handler": header_trust_handler_seen = True if trust_trace_headers_value and not header_trust_handler_seen: capture["arglist"].append_child(Comma()) handler_kwarg = KeywordArg( Name("trust_headers"), trust_trace_headers_value ) handler = Call(Name("StaticTrustHandler"), args=[handler_kwarg]) kwarg = KeywordArg(Name("header_trust_handler"), handler) kwarg.prefix = " " capture["arglist"].append_child(kwarg) self.added_static_trust_handler = True
def transform(self, node, results): assert results bare_print = results.get("bare") if bare_print: # Special-case print all by itself. bare_print.replace(Call(Name(u"print"), [], prefix=bare_print.prefix)) # The "from __future__ import print_function"" declaration is added # by the fix_print_with_import fixer, so we skip it here. # add_future(node, u'print_function') return assert node.children[0] == Name(u"print") args = node.children[1:] if len(args) == 1 and parend_expr.match(args[0]): # We don't want to keep sticking parens around an # already-parenthesised expression. return sep = end = file = None if args and args[-1] == Comma(): args = args[:-1] end = " " if args and args[0] == pytree.Leaf(token.RIGHTSHIFT, u">>"): assert len(args) >= 2 file = args[1].clone() args = args[3:] # Strip a possible comma after the file expression # Now synthesize a print(args, sep=..., end=..., file=...) node. l_args = [arg.clone() for arg in args] if l_args: l_args[0].prefix = u"" if sep is not None or end is not None or file is not None: if sep is not None: self.add_kwarg(l_args, u"sep", String(repr(sep))) if end is not None: self.add_kwarg(l_args, u"end", String(repr(end))) if file is not None: self.add_kwarg(l_args, u"file", file) n_stmt = Call(Name(u"print"), l_args) n_stmt.prefix = node.prefix # Note that there are corner cases where adding this future-import is # incorrect, for example when the file also has a 'print ()' statement # that was intended to print "()". # add_future(node, u'print_function') return n_stmt
def transform(self, node, results): assert results bare_print = results.get("bare") if bare_print: # Special-case print all by itself. bare_print.replace( Call(Name(u"print"), [], prefix=bare_print.prefix)) # The "from __future__ import print_function"" declaration is added # by the fix_print_with_import fixer, so we skip it here. # add_future(node, u'print_function') return assert node.children[0] == Name(u"print") args = node.children[1:] if len(args) == 1 and parend_expr.match(args[0]): # We don't want to keep sticking parens around an # already-parenthesised expression. return sep = end = file = None if args and args[-1] == Comma(): args = args[:-1] end = " " if args and args[0] == pytree.Leaf(token.RIGHTSHIFT, u">>"): assert len(args) >= 2 file = args[1].clone() args = args[3:] # Strip a possible comma after the file expression # Now synthesize a print(args, sep=..., end=..., file=...) node. l_args = [arg.clone() for arg in args] if l_args: l_args[0].prefix = u"" if sep is not None or end is not None or file is not None: if sep is not None: self.add_kwarg(l_args, u"sep", String(repr(sep))) if end is not None: self.add_kwarg(l_args, u"end", String(repr(end))) if file is not None: self.add_kwarg(l_args, u"file", file) n_stmt = Call(Name(u"print"), l_args) n_stmt.prefix = node.prefix # Note that there are corner cases where adding this future-import is # incorrect, for example when the file also has a 'print ()' statement # that was intended to print "()". # add_future(node, u'print_function') return n_stmt
def transform(self, node, results): func = results['func'] touch_import(None, 'collections', node=node) args = [func.clone(), String(', ')] args.extend(Attr(Name('collections'), Name('Callable'))) return Call(Name('isinstance'), args, prefix=node.prefix)
def transform(self, node, results): head = results["head"] method = results["method"][0] # Extract node for method name tail = results["tail"] syms = self.syms method_name = method.value isiter = method_name.startswith(u"iter") isview = method_name.startswith(u"view") head = [n.clone() for n in head] tail = [n.clone() for n in tail] # no changes neccessary if the call is in a special context special = not tail and self.in_special_context(node, isiter) new = pytree.Node(syms.power, head) new.prefix = u"" if isiter or isview: # replace the method with the six function # e.g. d.iteritems() -> from six import iteritems\n iteritems(d) new = Call(Name(method_name), [new]) touch_import_top('six', method_name, node) elif special: # it is not neccessary to change this case return node elif method_name in ("items", "values"): # ensure to return a list in python 3 new = Call(Name(u"list" + method_name), [new]) touch_import_top('future.utils', 'list' + method_name, node) else: # method_name is "keys"; removed it and cast the dict to list new = Call(Name(u"list"), [new]) if tail: new = pytree.Node(syms.power, [new] + tail) new.prefix = node.prefix return new
def _unicode(arg): """ Calls unicode() on the arg in the node. """ prefix = arg.prefix arg = arg.clone() arg.prefix = "" ret = Call(Name("unicode", prefix=prefix), [arg]) return ret
def transform(self, node, results): # wrap string in a call to tr() literal = results["s"] literal.replace(Call(Name("tr"), args=[literal.clone()]), ) # drop a leading comment node.prefix = re.sub(r"# TODO: i18n.*\n\s*", "", node.prefix) return node
def transform(self, node, results): assert results base = results.get('base') if not base: return touch_import(None, u'six', node) base = [n.clone() for n in base] base[0].prefix = u"" node.replace(Call(Name(u"six.advance_iterator", prefix=node.prefix), base))
def _Call(self, name, args=None, prefix=None): """Help the next test""" children = [] if isinstance(args, list): for arg in args: children.append(arg) children.append(Comma()) children.pop() return Call(Name(name), children, prefix)
def transform(self, node, results): assert results base = results.get('base') if not base: return method = results['method'][0] touch_import(None, u'six', node) base = [n.clone() for n in base] base[0].prefix = u"" node.replace( Call(Name(u"six.%s" % method.value, prefix=node.prefix), base))
def transform(self, node, results): if 'name' in results: touch_import(None, u'six', node) name = results['name'] name.replace(Name(u'six.text_type', prefix=name.prefix)) elif node.type == token.STRING and _literal_re.match(node.value): touch_import(None, u'six', node) new = node.clone() new.value = new.value[1:] new.prefix = '' node.replace(Call(Name(u'six.u', prefix=node.prefix), [new]))
def transform(self, node, results): assert results bare_print = results.get('bare') if bare_print: # Special-case print all by itself bare_print.replace(Call(Name('print'), [], prefix=bare_print.prefix)) return assert node.children[0] == Name('print') args = node.children[1:] if len(args) == 1 and parend_expr.match(args[0]): # We don't want to keep sticking parens around an # already-parenthesised expression. return sep = end = file = None if args and args[-1] == Comma(): args = args[:-1] end = ' ' if args and args[0] == pytree.Leaf(token.RIGHTSHIFT, '>>'): assert len(args) >= 2 file = args[1].clone() args = args[3:] # Strip a possible comma after the file expression # Now synthesize a print(args, sep=..., end=..., file=...) node. l_args = [arg.clone() for arg in args] if l_args: l_args[0].prefix = '' if sep is not None or end is not None or file is not None: if sep is not None: self.add_kwarg(l_args, 'sep', String(repr(sep))) if end is not None: self.add_kwarg(l_args, 'end', String(repr(end))) if file is not None: self.add_kwarg(l_args, 'file', file) n_stmt = Call(Name('print'), l_args) n_stmt.prefix = node.prefix self.found_print = True return n_stmt
def transform(self, node, results): exc = results["exc"].clone() val = results["val"].clone() tb = results["tb"].clone() exc.prefix = u"" val.prefix = tb.prefix = u" " touch_import(None, u'six', node) return Call(Name(u"six.reraise"), [exc, Comma(), val, Comma(), tb], prefix=node.prefix)
def AlmostOp(places_op, delta_op, first, second, kws): first.prefix = "" second.prefix = "" approx_args = [second] if kws.get('delta', None) is not None: kws['delta'].prefix = "" abs_arg = KeywordArg(Name('abs'), kws['delta']) abs_arg.prefix = " " approx_args.extend([Comma(), abs_arg]) approx_op = Call(Name("pytest.approx"), approx_args) return CompOp(places_op, first, approx_op, {})
def transform(self, node, results): assert results bare_print = results.get("bare") if bare_print: # Special-case print all by itself bare_print.replace(Call(Name(u"print"), [], prefix=bare_print.prefix)) return assert node.children[0] == Name(u"print") args = node.children[1:] if len(args) == 1 and parend_expr.match(args[0]): # We don't want to keep sticking parens around an # already-parenthesised expression. return sep = end = file = None if args and args[-1] == Comma(): args = args[:-1] end = " " if args and args[0] == pytree.Leaf(token.RIGHTSHIFT, u">>"): assert len(args) >= 2 file = args[1].clone() args = args[3:] # Strip a possible comma after the file expression # Now synthesize a print(args, sep=..., end=..., file=...) node. l_args = [arg.clone() for arg in args] if l_args: l_args[0].prefix = u"" if sep is not None or end is not None or file is not None: if sep is not None: self.add_kwarg(l_args, u"sep", String(repr(sep))) if end is not None: self.add_kwarg(l_args, u"end", String(repr(end))) if file is not None: self.add_kwarg(l_args, u"file", file) n_stmt = Call(Name(u"print"), l_args) n_stmt.prefix = node.prefix touch_import(u'__future__', u'print_function', node) return n_stmt
def RaisesOp(context, exceptionClass, indent, kws, arglist): with_item = Call(Name(context), [exceptionClass]) with_item.prefix = " " args = [] arglist = [a.clone() for a in arglist.children[4:]] if arglist: arglist[0].prefix="" func = None # :fixme: this uses hardcoded parameter names, which may change if 'callableObj' in kws: func = kws['callableObj'] elif 'callable_obj' in kws: func = kws['callable_obj'] elif kws['args']: # any arguments assigned to `*args` func = kws['args'][0] else: raise NotImplementedError('with %s is not implemented' % context) if func is unittest.case._sentinel: # with self.assertRaises(SomeException): return Node(syms.with_stmt, [with_item]) suite = Call(func, arglist) suite.prefix = indent + (4 * " ") return Node(syms.with_stmt, [Name('with'), with_item, Name(':'), Newline(), suite])
def RaisesOp(context, exceptionClass, indent, kws, arglist, node): with_item = Call(Name(context), [exceptionClass]) with_item.prefix = " " args = [] arglist = [a.clone() for a in arglist.children[4:]] if arglist: arglist[0].prefix = "" func = None # :fixme: this uses hardcoded parameter names, which may change if 'callableObj' in kws: func = kws['callableObj'] elif 'callable_obj' in kws: func = kws['callable_obj'] elif kws['args']: # any arguments assigned to `*args` func = kws['args'][0] else: func = None if func is None: # Context manager return Node(syms.with_stmt, [with_item]) if func.type == syms.lambdef: suite = func.children[-1].clone() else: suite = Call(func, arglist) suite.prefix = indent + (4 * " ") return Node( syms.with_stmt, [Name('with'), with_item, Name(':'), Newline(), suite])
def transform(self, node, results): assert results bare_print = results.get("bare") if bare_print: # Special-case print all by itself bare_print.replace( Call(Name(u"print"), [], prefix=bare_print.prefix)) return assert node.children[0] == Name(u"print") args = node.children[1:] if len(args) == 1 and parend_expr.match(args[0]): # We don't want to keep sticking parens around an # already-parenthesised expression. return sep = end = file = None if args and args[-1] == Comma(): args = args[:-1] end = " " if args and args[0] == pytree.Leaf(token.RIGHTSHIFT, u">>"): assert len(args) >= 2 file = args[1].clone() args = args[3:] # Strip a possible comma after the file expression # Now synthesize a print(args, sep=..., end=..., file=...) node. l_args = [arg.clone() for arg in args] if l_args: l_args[0].prefix = u"" if sep is not None or end is not None or file is not None: if sep is not None: self.add_kwarg(l_args, u"sep", String(repr(sep))) if end is not None: self.add_kwarg(l_args, u"end", String(repr(end))) if file is not None: self.add_kwarg(l_args, u"file", file) n_stmt = Call(Name(u"print"), l_args) n_stmt.prefix = node.prefix add_future(node, u'print_function') return n_stmt
def transform(self, node, results): syms = self.syms exc = results['exc'].clone() if 'exc' in results else None val = results['val'].clone() if 'val' in results else None tb = results['tb'].clone() if 'tb' in results else None exc.prefix = ' ' #Change Error() to Error, if there are no arguments to pass in. try: if len(exc.children[1].children) == 2: exc = String(exc.children[0]) except IndexError: pass if tb and val: exc.prefix = '' args = [exc] args.append(String(", ")) args.append(val) args.append(String(", ")) args.append(tb) raise_stmt = Call(Name("six.reraise"), args) raise_stmt.prefix = node.prefix return raise_stmt elif val: val.prefix = '' val = [val] raise_stmt = pytree.Node(syms.raise_stmt, [Name("raise"), Call(exc, val)]) else: raise_stmt = pytree.Node(syms.raise_stmt, [Name("raise"), String(exc)]) raise_stmt.prefix = node.prefix return raise_stmt
def fix_explicit_context(self, node, results): pre, name, post, source = (results.get(n) for n in (u"pre", u"name", u"post", u"source")) pre = [n.clone() for n in pre if n.type == token.NAME] name.prefix = u" " post = [n.clone() for n in post if n.type == token.NAME] target = [n.clone() for n in commatize(pre + [name.clone()] + post)] # to make the special-case fix for "*z, = ..." correct with the least # amount of modification, make the left-side into a guaranteed tuple target.append(Comma()) source.prefix = u"" setup_line = Assign(Name(self.LISTNAME), Call(Name(u"list"), [source.clone()])) power_line = Assign(target, assignment_source(len(pre), len(post), self.LISTNAME, self.ITERNAME)) return setup_line, power_line
def transform(self, node, results): assert results syms = self.syms anchor = results["anchor"] # There are 2 types of nodes in the AST - Node and Leaf. # Leaf nodes have a prefix and suffix that are meant for whitespaces and comments. # It usually suffices to use the prefix only as the prefix of a node is the suffix # of its previous node. prefix = node.prefix # before is the identifier that precedes the '.' before the 'None'. before = [n.clone() for n in results["before"]] if len(before) == 1: before = before[0] else: before = pytree.Node(syms.power, before) noneKeywd = String(repr("None")) l_args = [before, Comma(), noneKeywd] if l_args: l_args[0].prefix = u"" l_args[2].prefix = u" " new = Call(Name(u"getattr"), l_args) new.prefix = prefix return new
def RaisesOp(context, exceptionClass, indent, kws, arglist, node): with_item = Call(Name(context), [exceptionClass]) with_item.prefix = " " args = [] arglist = [a.clone() for a in arglist.children[4:]] if arglist: arglist[0].prefix="" func = None # :fixme: this uses hardcoded parameter names, which may change if 'callableObj' in kws: func = kws['callableObj'] elif 'callable_obj' in kws: func = kws['callable_obj'] elif kws['args']: # any arguments assigned to `*args` func = kws['args'][0] else: func = None if func is None: # Context manager return Node(syms.with_stmt, [with_item]) if func.type == syms.lambdef: suite = func.children[-1].clone() else: suite = Call(func, arglist) suite.prefix = indent + (4 * " ") return Node(syms.with_stmt, [Name('with'), with_item, Name(':'), Newline(), suite])
def deal_term(node): from lib2to3.fixer_util import Call args = [] args += get_atom(node.children[0]) for i in range(1, len(node.children)): if i % 2 == 1: continue args += get_atom(node.children[i]) temp = len(args) - 1 for i in range(temp): args.insert(2 * i + 1, Leaf(12, ',')) return Node(syms.simple_stmt,[\ Call(Leaf(1,'printf'),args), Leaf(1, ';'), Leaf(4, '\r\n'),])
def transform_isinstance(self, node, results): x = results["x"].clone() # The thing inside of type() T = results["T"].clone() # The type being compared against x.set_prefix("") T.set_prefix(" ") test = Call(Name("isinstance"), [x, Comma(), T]) if "n" in results: test.set_prefix(" ") test = Node(syms.not_test, [Name("not"), test]) test.set_prefix(node.get_prefix()) return test
def wrap_in_fn_call(fn_name, args, prefix=None): """ Example: >>> wrap_in_fn_call("oldstr", (arg,)) oldstr(arg) >>> wrap_in_fn_call("olddiv", (arg1, arg2)) olddiv(arg1, arg2) """ assert len(args) > 0 if len(args) == 1: newargs = args elif len(args) == 2: expr1, expr2 = args newargs = [expr1, Comma(), expr2] else: assert NotImplementedError('write me') return Call(Name(fn_name), newargs, prefix=prefix)
def wrap_in_fn_call(fn_name, args, prefix=None): """ Example: >>> wrap_in_fn_call("oldstr", (arg,)) oldstr(arg) >>> wrap_in_fn_call("olddiv", (arg1, arg2)) olddiv(arg1, arg2) >>> wrap_in_fn_call("olddiv", [arg1, comma, arg2, comma, arg3]) olddiv(arg1, arg2, arg3) """ assert len(args) > 0 if len(args) == 2: expr1, expr2 = args newargs = [expr1, Comma(), expr2] else: newargs = args return Call(Name(fn_name), newargs, prefix=prefix)
def RaisesOp(context, exceptionClass, indent, kws, arglist): with_item = Call(Name(context), [exceptionClass]) with_item.prefix = " " args = [] arglist = [a.clone() for a in arglist.children[4:]] if arglist: arglist[0].prefix="" # :fixme: this uses hardcoded parameter names, which may change if 'callableObj' in kws: suite = Call(kws['callableObj'], arglist) elif 'callable_obj' in kws: suite = Call(kws['callable_obj'], arglist) elif kws['args']: # any arguments assigned to `*args` suite = Call(kws['args'][0], arglist) else: raise NotImplementedError('with %s is not implemented' % context) suite.prefix = indent + (4 * " ") return Node(syms.with_stmt, [Name('with'), with_item, Name(':'), Newline(), suite])