Пример #1
0
        def lazy_aliasing() -> None:
            # We should find the first place where the alias is used and put it
            # right above.  This way we don't need to look at the value at all.
            _, prefix = get_offset_and_prefix(body, skip_assignments=True)
            name_node = Leaf(token.NAME, name)
            for _offset, stmt in enumerate(body.children):
                if name_used_in_node(stmt, name_node):
                    break
            else:
                _offset = -1

            body.children.insert(
                _offset,
                Node(
                    syms.simple_stmt,
                    [
                        Node(
                            syms.expr_stmt,
                            [
                                Leaf(token.NAME, name),
                                new(_eq),
                                value,
                            ],
                        ),
                        new(_newline),
                    ],
                    prefix=prefix.lstrip('\n'),
                ),
            )
Пример #2
0
def add_sep_part(sep, pos, lst):
    if sep is not None and not isNone(sep) and \
       not (sep.type == token.STRING and sep.value in ("' '", '" "')):
        temp = []
        for arg in pos:
            temp.append(_unicode(arg.clone()))
            if sys.version_info >= (2, 6):
                warnings.warn(
                    "Calling unicode() on what may be a bytes object")
            temp.append(Comma())
        del temp[-1]
        sep = sep.clone()
        sep.prefix = " "
        args = Node(syms.listmaker, temp)
        new_list = Node(syms.atom,
                        [Leaf(token.LSQB, "["), args,
                         Leaf(token.RSQB, "]")])
        join_arg = Node(syms.trailer, [LParen(), new_list, RParen()])
        sep_join = Node(syms.power,
                        [sep, Node(syms.trailer, [Dot(), Name("join")])])
        lst.append(sep_join)
        lst.append(join_arg)
    else:
        if pos:
            pos[0].prefix = " "
        for arg in pos:
            lst.append(arg.clone())
            lst.append(Comma())
        del lst[-1]
Пример #3
0
	def transform(self, node, results):
		args = []
		for i in range(len(node.children[0].children)):
			if i%2==1:
				if i!=1:
					args.append(Leaf(1, '&&'))
				args.append(Leaf(7, '('))
				args.append(node.children[0].children[i].clone())
				args.append(Leaf(8, ')'))
		args = [\
			Leaf(1, 'if'),Leaf(7, '('),\
			Leaf(1, '!'),Leaf(7, '('),\
			Node(syms.and_expr,args),\
			Leaf(8, ')'),Leaf(8, ')'),\
			Leaf(token.LBRACE, '{'),\
			Node(syms.raise_stmt, [
                        Leaf(1, 'throw'),
                        Leaf(3, '"AssertionError"'),
						Leaf(1, ';'),
                ]),
			Leaf(token.RBRACE, '}'),Leaf(4, '\r\n')
		]
		
		result = Node(syms.testlist1,args)
		result.prefix = node.prefix
		return result
Пример #4
0
def _nai_alias(alias, node):
    # Comments below show example imports that match the rule.
    name = Leaf(token.NAME, alias.name)
    if not alias.asname or alias.asname == alias.name:
        # import hay, x, stack
        # from field import hay, s, stack
        if node.type in (syms.dotted_as_names, syms.import_as_names):
            return name in node.children

        # import x as x
        # from field import x as x
        if node.type in (syms.dotted_as_name, syms.import_as_name):
            return [name, _as, name] == node.children

        # import x
        return node == name

    asname = Leaf(token.NAME, alias.asname)
    dotted_as_name = Node(syms.dotted_as_name, [name, _as, asname])
    # import hay as stack, x as y
    if node.type == syms.dotted_as_names:
        return dotted_as_name in node.children

    import_as_name = Node(syms.import_as_name, [name, _as, asname])
    # from field import hay as stack, x as y
    if node.type == syms.import_as_names:
        return import_as_name in node.children

    # import x as y
    # from field import x as y
    return node in (dotted_as_name, import_as_name)
Пример #5
0
def parse(code):
    """String -> AST

    Parse the string and return its AST representation. May raise
    a ParseError exception.
    """
    added_newline = False
    if not code.endswith("\n"):
        code += "\n"
        added_newline = True

    try:
        drv = driver.Driver(pygram.python_grammar, pytree.convert)
        result = drv.parse_string(code, True)
    except ParseError:
        log.debug("Had problems parsing:\n%s\n" % quoted_block(code))
        raise

    # Always return a Node, not a Leaf.
    if isinstance(result, Leaf):
        result = Node(syms.file_input, [result])

    result.added_newline = added_newline

    return result
Пример #6
0
 def get_dotted_import_replacement(self,
                                   name_node,
                                   attr_node,
                                   mapping=MAPPING,
                                   renamed=None):
     u"""
     For (http, client) given and httplib being the correct replacement,
     returns (httplib as client, None)
     For (test, support) given and test.test_support being the replacement,
     returns (test, test_support as support)
     """
     full_name = name_node.value + u'.' + attr_node.value
     replacement = mapping[full_name]
     if u'.' in replacement:
         new_name, new_attr = replacement.split(u'.')
         if renamed is None:
             return Name(new_name, prefix=name_node.prefix), Node(
                 syms.dotted_as_name, [
                     Name(new_attr, prefix=attr_node.prefix),
                     Name(u'as', prefix=u" "),
                     attr_node.clone()
                 ])
         else:
             return Name(new_name, prefix=name_node.prefix), Name(
                 new_attr, prefix=attr_node.prefix)
     else:
         return Node(syms.dotted_as_name, [
             Name(replacement, prefix=name_node.prefix),
             Name(u'as', prefix=u' '),
             Name(attr_node.value, prefix=attr_node.prefix)
         ]), None
Пример #7
0
 def transform(self, node, results):
     args = []
     item_id = 0
     while item_id < len(node.children):
         if (node.children[item_id].__class__.__name__ == "Leaf"):
             if node.children[item_id].value == ':':
                 #加花括号
                 args += [
                     Leaf(token.LBRACE, '{'),
                     node.children[item_id + 1].clone(),
                     Leaf(token.RBRACE, '}'),
                     Leaf(4, '\r\n')
                 ]
                 item_id += 1
             #if,elif处理
             elif (node.children[item_id].value
                   == 'elif') | (node.children[item_id].value == 'if'):
                 if node.children[item_id].value == 'elif':
                     leaf_temp = Leaf(1, 'if')
                     leaf_temp.prefix = " "
                     args += [Leaf(1, 'else'), leaf_temp]
                 else:
                     args += [node.children[item_id].clone()]
                 args += [Leaf(7, '(')]
                 args += [node.children[item_id + 1].clone()]
                 args += [Leaf(8, ')')]
                 item_id += 1
             else:
                 args += [node.children[item_id].clone()]
         else:
             print("\nFixerError_if\n")
         item_id += 1
     new = Node(node.type, args)
     new.prefix = node.prefix
     return new
Пример #8
0
def suitify(parent):
    """
    Turn the stuff after the first colon in parent's children
    into a suite, if it wasn't already
    """
    for node in parent.children:
        if node.type == syms.suite:
            # already in the prefered format, do nothing
            return

    # One-liners have no suite node, we have to fake one up
    for i, node in enumerate(parent.children):
        if node.type == token.COLON:
            break
    else:
        raise ValueError(u"No class suite and no ':'!")
    # Move everything into a suite node
    suite = Node(syms.suite, [
        Newline(),
        Leaf(token.INDENT,
             indentation(node) + indentation_step(node))
    ])
    one_node = parent.children[i + 1]
    one_node.remove()
    one_node.prefix = u''
    suite.append_child(one_node)
    parent.append_child(suite)
Пример #9
0
def parse(code):
    """String -> AST

    Parse the string and return its AST representation. May raise
    a ParseError exception.
    """
    added_newline = False
    if not code.endswith("\n"):
        code += "\n"
        added_newline = True

    try:
        drv = driver.Driver(pygram.python_grammar, pytree.convert)
        result = drv.parse_string(code, True)
    except ParseError:
        log.debug("Had problems parsing:\n%s\n" % quoted_block(code))
        raise

    # Always return a Node, not a Leaf.
    if isinstance(result, Leaf):
        result = Node(syms.file_input, [result])

    result.added_newline = added_newline

    return result
Пример #10
0
def ImportAsName(name, as_name, prefix=None):
    new_name = Name(name)
    new_as = Name(u"as", prefix=u" ")
    new_as_name = Name(as_name, prefix=u" ")
    new_node = Node(syms.import_as_name, [new_name, new_as, new_as_name])
    if prefix is not None:
        new_node.prefix = prefix
    return new_node
Пример #11
0
def ImportAsName(name, as_name, prefix=None):
    new_name = Name(name)
    new_as = Name(u"as", prefix=u" ")
    new_as_name = Name(as_name, prefix=u" ")
    new_node = Node(syms.import_as_name, [new_name, new_as, new_as_name])
    if prefix is not None:
        new_node.prefix = prefix
    return new_node
Пример #12
0
def _c_subscript(sub):
    return Node(
        syms.power,
        [
            convert_annotation(sub.value),
            Node(syms.trailer, [new(_lsqb), convert_annotation(sub.slice), new(_rsqb)]),
        ],
    )
Пример #13
0
        def _CreateCode(indent, package, symbols, comment):
            """
            Create code:
                from <package> import <symbols> # <comment>
            """
            # children: the children nodes for the final from-import statement
            children = [
                Name('from', prefix=' ' * indent),
                Name(package, prefix=' '),
                Name('import', prefix=' '),
            ]

            # name_leaf: list of leaf nodes with the symbols to import
            name_leafs = []
            symbols = sorted(symbols)
            for i, i_symbol in enumerate(symbols):
                prefix = ' ' if i == 0 else ', '
                name_leafs.append(i_symbol.CreateNameNode(prefix))

            # nodes_wrap: if true, we need to wrap the import statement
            nodes_wrap = False
            line_len = 0
            line_len += six.moves.reduce(lambda x, y: x + y,
                                         map(len, map(str, children)), 0)
            line_len += six.moves.reduce(lambda x, y: x + y,
                                         map(len, map(str, name_leafs)), 0)
            if line_len > page_width:
                # Add parenthesis around the "from" names
                name_leafs[0].prefix = ''
                name_leafs.insert(0, Name('(', prefix=' '))
                name_leafs.append(Name(')'))
                nodes_wrap = True

            # Adds the name_leafs to the children list
            children += [
                Node(pygram.python_symbols.import_as_names, name_leafs)
            ]

            # from_import: the final node for the import statement
            from_import = Node(pygram.python_symbols.import_from, children)

            # result: a simple-statement node with the import statement and
            # EOL.
            new_line = Newline()
            new_line.prefix = comment
            result = Node(
                pygram.python_symbols.simple_stmt,
                children=[
                    from_import,
                    new_line,
                ],
            )

            # Wrap nodes if necessary (see nodes_wrap above)
            if nodes_wrap:
                ImportBlock.TextWrapForNode(result, page_width, indent)

            return result
Пример #14
0
def touch_import_top(package, name_to_import, node):
    """Works like `does_tree_import` but adds an import statement at the
    top if it was not imported (but below any __future__ imports).

    Calling this multiple times adds them in reverse order.
        
    Based on lib2to3.fixer_util.touch_import()
    """
    root = find_root(node)

    if does_tree_import(package, name_to_import, root):
        return

    # Look for __future__ imports and insert below them
    found = False
    for name in [
            'absolute_import', 'division', 'print_function', 'unicode_literals'
    ]:
        if does_tree_import('__future__', name, root):
            found = True
            break
    if found:
        # At least one __future__ import. We want to loop until we've seen them
        # all.
        start, end = None, None
        for idx, node in enumerate(root.children):
            if check_future_import(node):
                start = idx
                # Start looping
                idx2 = start
                while node:
                    node = node.next_sibling
                    idx2 += 1
                    if not check_future_import(node):
                        end = idx2
                        break
                break
        assert start is not None
        assert end is not None
        insert_pos = end
    else:
        # No __future__ imports
        for idx, node in enumerate(root.children):
            if node.type == syms.simple_stmt:  # and node.children and node.children[0].type == token.STRING):
                break
        insert_pos = idx

    if package is None:
        import_ = Node(syms.import_name, [
            Leaf(token.NAME, u"import"),
            Leaf(token.NAME, name_to_import, prefix=u" ")
        ])
    else:
        import_ = FromImport(package,
                             [Leaf(token.NAME, name_to_import, prefix=u" ")])

    children = [import_, Newline()]
    root.insert_child(insert_pos, Node(syms.simple_stmt, children))
Пример #15
0
	def transform(self, node, results):
		args = [Leaf(1, 'while')]
		args += [Leaf(7, '(')]
		args += [n.clone() for n in results["test_content"]]
		args += [Leaf(8, ')'),Leaf(token.LBRACE, '{')]
		args += [n.clone() for n in results["content"]]
		new = Node(node.type,args)
		new.prefix = node.prefix 
		return new
Пример #16
0
def _c_attribute(attr):
    return Node(
        syms.power,
        [
            _convert_annotation(attr.value),
            Node(syms.trailer,
                 [new(_dot), Leaf(token.NAME, attr.attr)]),
        ],
    )
Пример #17
0
def form_eqs(node1,node2):
	result = Node(syms.simple_stmt,[\
		Node(syms.expr_stmt,[\
			node1.clone(),\
			Leaf(22, '='),\
			node2.clone()]),\
		Leaf(4, '\r\n')\
		])
	result.changed()
	return result
Пример #18
0
def _c_list(l):
    contents = [_convert_annotation(elt) for elt in l.elts]
    for index in range(len(contents) - 1, 0, -1):
        contents[index].prefix = " "
        contents.insert(index, new(_comma))

    list_literal = [new(_lsqb), new(_rsqb)]
    if contents:
        list_literal.insert(1, Node(syms.listmaker, contents))
    return Node(syms.atom, list_literal)
Пример #19
0
    def transform_arglist_to_keywords(self, arglist_node, alg_object):
        """Takes a node that points to argument list and transforms
        it to all keyword=values
            @param arglist_node The node that points to the argument list
            @param alg_object The algorithm object that corresponds to this list
        """
        ordered_props = alg_object.orderedProperties()
        # Special case where the arglist has no children
        if len(arglist_node.children) == 0:
            arglist_node = Node(syms.argument, [Leaf(token.NAME,ordered_props[0]),Leaf(token.EQUAL,"="),
                                                Leaf(arglist_node.type,arglist_node.value)])
            return arglist_node
        # Quick check: A 3 arg leaf list with an equals at the 2nd element needs nothing doing
        if len(arglist_node.children) == 3 and arglist_node.children[1].type == token.EQUAL:
            return arglist_node

        # Construct our argument list from the children to make sure we separate out whole comma-separated
        # sections i.e get embedded lists correct
        args = [[]] # Each list will be delimited by a comma
        nargs = 0
        index = 0
        for node in arglist_node.children:
            if node.type == token.COMMA:
                args.append(node)
                args.append([]) # new arg list
                index += 2 # include comma
                nargs += 1
            else:
                args[index].append(node)

        # Ordered props
        prop_index = 0 # List has commas so standard enumerate won't do the trick
        arg_nodes = [] # Holds the final node list
        for arg_list in args:
            if isinstance(arg_list, Leaf): # Must be comma from construction above
                arg_nodes.append(arg_list)
            else:
                first = arg_list[0]
                if not (isinstance(first, Node) and first.type == syms.argument):
                    prop_name = ordered_props[prop_index]
                    children=[Leaf(token.NAME,prop_name),Leaf(token.EQUAL,"=")]
                    children.extend(arg_list)
                    for c in children:
                        c.parent = None # A new node requires all old parent nodes to be None
                    arg_nodes.append(Node(syms.argument, children))
                else:
                    for node in arg_list:
                        arg_nodes.append(node)
                # Move to the next property
                prop_index += 1

        arglist_node.children = arg_nodes
        return arglist_node
Пример #20
0
 def transform(self, node, results):
     args = [Leaf(1, 'for')]
     args += [Leaf(7, '(')]
     args += [Leaf(1, 'auto')]  #c++11
     args += [n.clone() for n in results["in_before"]]
     args += [Leaf(token.COLON, ':')]
     args += [n.clone() for n in results["in_after"]]
     args += [Leaf(8, ')'), Leaf(token.LBRACE, '{')]
     args += [n.clone() for n in results["content"]]
     new = Node(node.type, args)
     new.prefix = node.prefix
     return new
Пример #21
0
def _c_call(call):
    contents = [convert_annotation(arg) for arg in call.args]
    contents.extend(convert_annotation(kwarg) for kwarg in call.keywords)
    for index in range(len(contents) - 1, 0, -1):
        contents[index].prefix = " "
        contents.insert(index, new(_comma))

    call_args = [new(_lpar), new(_rpar)]
    if contents:
        call_args.insert(1, Node(syms.arglist, contents))
    return Node(syms.power,
                [convert_annotation(call.func),
                 Node(syms.trailer, call_args)])
Пример #22
0
def fix_main(node):
	main_list = []
	del_list =[]
	
	if(len(node.children)==0):
		return node
	# 处理文件头多行注释
	temp = False
	if (node.children[0].type==syms.simple_stmt) \
		and (node.children[0].children[0].type==3):
		temp = node.children[0].clone()
		node.children[0].remove()
	
	for i in node.children:
		if(i.type==syms.funcdef)|(i.type==syms.async_funcdef)|(i.type==syms.classdef)|(i.type==syms.decorated):
			continue
		if len(i.children)!=0:
			if(i.children[0].type==syms.import_name)|(i.children[0].type==syms.import_from):
				continue
		main_list.append(i.clone())
		del_list.append(i)
	
	for i in del_list:
		i.remove()
	if temp:
		node.insert_child(0,temp)
	args = [
		Leaf(1, 'def'),
		Leaf(1, 'main',prefix=' '),
		Node(syms.parameters, [
				Leaf(7, '('),
				Leaf(8, ')'),
		]),
		Leaf(11, ':'),
		Leaf(4, '\r\n')
	]
	args+=main_list
	args+=[Node(syms.suite, [
				Leaf(5, '\t'),
				Node(syms.simple_stmt, [
						Node(syms.return_stmt, [
								Leaf(1, 'return '),
								Leaf(2, '0'),
						]),
						Leaf(4, '\r\n'),
				]),
				Leaf(6, '')
	])]
	main_node = Node(syms.funcdef,args)
	node.append_child(main_node)	
	
Пример #23
0
	def transform(self, node, results):
		args = []
		if results['first']:
			args.append(Node(syms.simple_stmt,[\
				Leaf(1, 'TODO_PyObject'),
				results['name'].clone(),
				Leaf(1, ';'),
				Leaf(4, '\r\n'),]))
		if results['out'][0].type==syms.trailer:
			args.append(deal_cout(results['out'][0].children[1]))
		args.append(deal_cin(results['name']))
		result = Node(syms.testlist1,args)
		result.prefix = node.prefix
		return result
Пример #24
0
def deal_cout(node):
    return Node(syms.simple_stmt,[\
     Node(syms.power, [
      Leaf(1, 'std'),
      Node(syms.trailer, [
       Leaf(23, ':'),
       Leaf(23, ':'),
       Leaf(1, 'cout'),
      ]),
     ]),
     Leaf(34, '<<'),
     node.clone(),
     Leaf(1, ';'),
     Leaf(4, '\r\n'),])
Пример #25
0
def future_import2(feature, node):
    """
    An alternative to future_import() which might not work ...
    """
    root = find_root(node)

    if does_tree_import(u"__future__", feature, node):
        return

    insert_pos = 0
    for idx, node in enumerate(root.children):
        if node.type == syms.simple_stmt and node.children and \
           node.children[0].type == token.STRING:
            insert_pos = idx + 1
            break

    for thing_after in root.children[insert_pos:]:
        if thing_after.type == token.NEWLINE:
            insert_pos += 1
            continue

        prefix = thing_after.prefix
        thing_after.prefix = u""
        break
    else:
        prefix = u""

    import_ = FromImport(u"__future__",
                         [Leaf(token.NAME, feature, prefix=u" ")])

    children = [import_, Newline()]
    root.insert_child(insert_pos,
                      Node(syms.simple_stmt, children, prefix=prefix))
Пример #26
0
def append_credentials(src,
                       access_key,
                       secret_key,
                       target='CREDENTIALS',
                       comment='Added by cornac'):
    if isinstance(src, str):
        if not src.endswith('\n'):
            src += '\n'
        src = parse_py(src)
    for varname, atom in iter_assign(src):
        if varname != target:
            continue

        if len(atom.children) == 2:
            # Atom is an empty dict.
            dictmaker = Node(syms.dictsetmaker, [])
            atom.children.insert(1, dictmaker)

        if atom.children[1].type != syms.dictsetmaker:
            raise ValueError(f"{target} is not a plain dict.")

        append_to_dict(atom, key=access_key, value=secret_key, comment=comment)
        break
    else:
        raise ValueError(f"{target} is not set.")
    return src
Пример #27
0
def _replace_node(node0: Node, node1: Node) -> None:
    suite0 = node0.children[-1]
    assert node_name(suite0) == "suite"
    for i, x in enumerate(suite0.children):
        if node_name(
                x) == "simple_stmt" and x.children[0].type == token.STRING:
            break
    has_comment0 = i < (len(suite0.children) - 1)

    suite1 = node1.children[-1]
    assert node_name(suite1) == "suite"
    before_comments1 = []
    for j, x in enumerate(suite1.children):
        before_comments1.append(x)
        if node_name(
                x) == "simple_stmt" and x.children[0].type == token.STRING:
            break
    has_comment1 = j < (len(suite1.children) - 1)

    if has_comment1:
        if has_comment0:
            suite0.children[i] = suite1.children[j]
        else:
            assert suite0.children[0].type == token.NEWLINE
            assert suite0.children[1].type == token.INDENT
            suite0.children = before_comments1 + suite0.children[1:]
        suite0.parent.changed()
    node0.children = [*node1.children[:-1], node0.children[-1]]
    node0.parent.changed()
Пример #28
0
def add_future(node, symbol):

    root = fixer_util.find_root(node)

    for idx, node in enumerate(root.children):
        if node.type == syms.simple_stmt and \
           len(node.children) > 0 and node.children[0].type == token.STRING:
            # skip over docstring
            continue
        names = check_future_import(node)
        if not names:
            # not a future statement; need to insert before this
            break
        if symbol in names:
            # already imported
            return

    import_ = fixer_util.FromImport('__future__',
                                    [Leaf(token.NAME, symbol, prefix=" ")])

    # Place after any comments or whitespace. (copyright, shebang etc.)
    import_.prefix = node.prefix
    node.prefix = ''

    children = [import_, fixer_util.Newline()]
    root.insert_child(idx, Node(syms.simple_stmt, children))
Пример #29
0
def get_annotated_param(node, arg, *, missing_ok=False):
    if node.type not in (token.NAME, syms.tname):
        raise NotImplementedError(f"unexpected node token: `{node}`")

    actual_ann = None
    if node.type == syms.tname:
        actual_ann = node.children[2]
        node = node.children[0]
    if not isinstance(node, Leaf) or arg.arg != node.value:
        raise ValueError(
            f".pyi file expects argument {arg.arg!r} next but argument " +
            f"{minimize_whitespace(str(node))!r} found in source")

    if arg.annotation is None:
        if actual_ann is None:
            if missing_ok:
                return new(node)

            raise ValueError(
                f".pyi file is missing annotation for {arg.arg!r} and source "
                + f"doesn't provide it either")

        ann = new(actual_ann)
    else:
        ann = convert_annotation(arg.annotation)
        ann.prefix = ' '

    if actual_ann is not None and actual_ann != ann:
        ann_str = minimize_whitespace(str(ann))
        actual_ann_str = minimize_whitespace(str(actual_ann))
        raise ValueError(
            f"incompatible annotation for {arg.arg!r}. Expected: " +
            f"{ann_str!r}, actual: {actual_ann_str!r}")

    return Node(syms.tname, [new(node), new(_colon), ann])
Пример #30
0
 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
Пример #31
0
def fix_not_a_in_b(node: LN, capture: Capture, filename: Filename):
    capture["element"].parent = None
    capture["collection"].parent = None

    new_comparison = Node(
        comparison,
        [
            capture["element"],
            Node(comp_op,
                 [Leaf(1, "not", prefix=" "),
                  Leaf(1, "in", prefix=" ")]),
            capture["collection"],
        ],
    )
    new_comparison.parent = node.parent
    return new_comparison
Пример #32
0
def future_import(feature, node):
    """
    This seems to work
    """
    root = find_root(node)

    if does_tree_import(u"__future__", feature, node):
        return

    for idx, node in enumerate(root.children):
        if node.type == syms.simple_stmt and \
           len(node.children) > 0 and node.children[0].type == token.STRING:
            # skip over docstring
            continue
        names = check_future_import(node)
        if not names:
            # not a future statement; need to insert before this
            break
        if feature in names:
            # already imported
            return

    import_ = FromImport(u'__future__',
                         [Leaf(token.NAME, feature, prefix=" ")])
    children = [import_, Newline()]
    root.insert_child(idx, Node(syms.simple_stmt, children))
Пример #33
0
 def transform(self, node, results):
     comp_for = results.get("comp_for").clone()
     is_dict = bool(results.get("col"))  # is it a dict?
     n1 = results.get("n1").clone()
     if is_dict:
         n2 = results.get("n2").clone()
         n2.prefix = " "
         impl_assign = tup((n1, n2))
     else:
         impl_assign = n1
     our_gencomp = Node(syms.listmaker, [(impl_assign), (comp_for)])
     if is_dict:
         new_node = Node(syms.power, [Name("dict"), parenthesize(Node(syms.atom, [our_gencomp]))])
     else:
         new_node = Node(syms.power, [Name("set"), parenthesize(Node(syms.atom, [our_gencomp]))])
     new_node.prefix = node.prefix
     return new_node
Пример #34
0
    def insert_annotation(self, arg_type):
        """Modifies tree to set string arg_type as our type annotation"""
        # maybe the right way to do this is to insert as next child
        # in our parent instead? Or could replace self._arg[-1]
        # with modified version of itself
        assert self.arg_type is None, 'already annotated'
        assert not self._wasModified, 'can only set annotation once'
        self._wasModified = True

        name = self._name_nodes[-1]
        assert name.type == token.NAME

        typed_name = Node(syms.tname,
                          [Leaf(token.NAME, self.name),
                           Leaf(token.COLON, ':'),
                           clean_clone(arg_type, False)])

        typed_name.prefix = name.prefix

        name.replace(typed_name)
Пример #35
0
def suitify(parent):
    u"""
    Turn the stuff after the first colon in parent's children
    into a suite, if it wasn't already
    """
    for node in parent.children:
        if node.type == syms.suite:
            # already in the prefered format, do nothing
            return

    # One-liners have no suite node, we have to fake one up
    for i, node in enumerate(parent.children):
        if node.type == token.COLON:
            break
    else:
        raise ValueError(u"No class suite and no ':'!")
    # Move everything into a suite node
    suite = Node(syms.suite, [Newline(), Leaf(token.INDENT, indentation(node) + indentation_step(node))])
    one_node = parent.children[i+1]
    one_node.remove()
    one_node.prefix = u''
    suite.append_child(one_node)
    parent.append_child(suite)
Пример #36
0
def wrap_parens(arg_node: PyNode, checker_fn: callable) -> PyNode or PyLeaf:
    """
    If a node that represents an argument to assert_ function should be grouped, return a new node that adds
    parentheses around arg_node. Otherwise, return arg_node.
    :param arg_node: the arg_node to parenthesize
    :return: the arg_node for the parenthesized expression, or the arg_node itself
    """
    if isinstance(arg_node, PyNode) and checker_fn(arg_node):
        # log.info('adding parens: "{}" ({}), "{}" ({})'.format(first_child, first_child.type, sibling, sibling.type))
        # sometimes arg_node has parent, need to remove it before giving to parenthesize() then re-insert:
        parent = arg_node.parent
        if parent is not None:
            pos_parent = arg_node.remove()
            new_node = parenthesize(arg_node)
            parent.insert_child(pos_parent, new_node)
        else:
            new_node = parenthesize(arg_node)

        new_node.prefix = arg_node.prefix
        arg_node.prefix = ''
        return new_node

    return arg_node
Пример #37
0
    def fix_leaves(self, node_to_split):
        parent_depth = find_indentation(node_to_split)
        new_indent = "%s%s" % (' ' * 4, parent_depth)
        # For now, just indent additional lines by 4 more spaces

        child_leaves = []
        combined_prefix = ""
        prev_leaf = None
        for index, leaf in enumerate(node_to_split.leaves()):
            if index and leaf.prefix.count('#'):
                if not combined_prefix:
                    combined_prefix = "%s#" % new_indent
                combined_prefix += leaf.prefix.split('#')[-1]

            # We want to strip all newlines so we can properly insert newlines
            # where they should be
            if leaf.type != token.NEWLINE:
                if leaf.prefix.count('\n') and index:
                    # If the line contains a newline, we need to strip all
                    # whitespace since there were leading indent spaces
                    if (prev_leaf and prev_leaf.type in [token.DOT, token.LPAR]
                        or leaf.type in [token.RPAR]):
                        leaf.prefix = ""
                    else:
                        leaf.prefix = " "

                    # Append any trailing inline comments to the combined
                    # prefix
                child_leaves.append(leaf)
                prev_leaf = leaf

        # Like TextWrapper, but for nodes. We split on MAX_CHARS - 1 since we
        # may need to insert a leading parenth. It's not great, but it would be
        # hard to do properly.
        split_leaves = wrap_leaves(child_leaves, width=MAX_CHARS - 1,
            subsequent_indent=new_indent)
        new_node = Node(node_to_split.type, [])

        # We want to keep track of if we are breaking inside a parenth
        open_count = 0
        need_parens = False
        for line_index, curr_line_nodes in enumerate(split_leaves):
            for node_index, curr_line_node in enumerate(curr_line_nodes):
                if line_index and not node_index:
                    # If first node in non-first line, reset prefix since there
                    # may have been spaces previously
                    curr_line_node.prefix = new_indent
                new_node.append_child(curr_line_node)
                if curr_line_node.type in OPENING_TOKENS:
                    open_count += 1
                if curr_line_node.type in CLOSING_TOKENS:
                    open_count -= 1

            if line_index != len(split_leaves) - 1:
                # Don't add newline at the end since it it part of the next
                # sibling
                new_node.append_child(Leaf(token.NEWLINE, '\n'))

                # Checks if we ended a line without being surrounded by parens
                if open_count <= 0:
                    need_parens = True
        if need_parens:
            # Parenthesize the parent if we're not inside parenths, braces,
            # brackets, since we inserted newlines between leaves
            parenth_before_equals = Leaf(token.EQUAL, "=") in split_leaves[0]
            self.parenthesize_parent(new_node, parenth_before_equals)
        node_to_split.replace(new_node)

        return combined_prefix