示例#1
0
def RaisesRegexOp(context, designator, exceptionClass, expected_regex, indent,
                  kws, arglist, node):
    expected_regex.prefix = ""
    arglist = [a.clone() for a in arglist.children]
    del arglist[2:4]  # remove pattern and comma
    arglist = Node(syms.arglist, arglist)
    with_stmt = RaisesOp(context, exceptionClass, indent, kws, arglist, node)
    with_stmt.insert_child(2, Name('as', prefix=" "))
    with_stmt.insert_child(3, Name(designator, prefix=" "))

    # if this is already part of a with statement we need to insert re.search
    # after the last leaf with content
    if node.parent.type == syms.with_stmt:
        parent_with = node.parent
        for leaf in reversed(list(parent_with.leaves())):
            if leaf.value.strip():
                break
        i = leaf.parent.children.index(leaf)
        leaf.parent.insert_child(i + 1, Newline())
        leaf.parent.insert_child(
            i + 2,
            Name('assert %s.match(%s)' % (designator, expected_regex),
                 prefix=indent))
        return with_stmt
    else:
        return Node(syms.suite, [
            with_stmt,
            Newline(),
            Name('assert %s.match(%s)' % (designator, expected_regex),
                 prefix=indent)
        ])
示例#2
0
    def transform(self, node, results):
        signame = results['signame']

        if 'emitter' in results:
            emitter = results.get("emitter")
            emitter = Name(''.join(map(str, emitter)))

            if 'sigarg' in results:
                args = results.get("args").clone()
                args.children = args.children[2:]
                if args.children:
                    args.children[0].prefix = ''
                res = Node(syms.power, [emitter, Name('.'), Name(signame), Name('.'), Name('emit')] + [ArgList([args])])
            else:
                res = Node(syms.power, [emitter, Name('.'), Name(signame), Name('.'), Name('emit()')])

        else:
            sender = results.get("sender").clone()
            method = results.get("method")
            if isinstance(method, list):
                method = method[0]
            method = method.clone()
            sender.prefix = node.prefix
            slot = results.get("slot").clone()
            slot.prefix = ""
            res = Node(syms.power, [sender, Name('.'), Name(signame), Name('.'), method] + [ArgList([slot])])
        return res
示例#3
0
    def transform(self, node, results):
        signal = results.get("signal").value
        signal = re.sub('^["\']([^(]+)(?:\(.*\))?["\']$', '\\1', signal)

        if 'emitter' in results:
            emitter = results.get("emitter").clone()
            emitter.prefix = node.prefix
            args = results.get("args").clone()
            args.children = args.children[2:]
            if args.children:
                args.children[0].prefix = ''
            res = Node(
                syms.power,
                [emitter,
                 Name('.'),
                 Name(signal),
                 Name('.'),
                 Name('emit')] + [ArgList([args])])
        else:
            sender = results.get("sender").clone()
            method = results.get("method")
            if isinstance(method, list):
                method = method[0]
            method = method.clone()
            sender.prefix = node.prefix
            slot = results.get("slot").clone()
            slot.prefix = ""
            res = Node(
                syms.power,
                [sender, Name('.'),
                 Name(signal),
                 Name('.'), method] + [ArgList([slot])])
        return res
示例#4
0
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])
示例#5
0
def _new_type_check_with_import(package, name, root, insert_pos):
    # type: (Optional[str], str, Node, int) -> None
    """
    Inserts a new TYPE_CHECKING block containing a new import statement for package and name

    Parameters
    -----------
    package : Optional[str]
    name : str
    root : Node
    insert_pos : int
    """
    # [Grammar]
    # if_stmt: 'if' namedexpr_test ':' suite ('elif' namedexpr_test ':' suite)* ['else' ':' suite]
    type_check_node = Node(syms.if_stmt,
                           [Leaf(token.NAME, 'if'),
                            Leaf(token.NAME, 'TYPE_CHECKING', prefix=" "),
                            Leaf(token.COLON, ':'),
                            # [Grammar]
                            # suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT
                            Node(syms.suite, [Leaf(token.NEWLINE, '\n'),
                                              Leaf(token.INDENT, '    '),
                                              Node(syms.simple_stmt,
                                                   [_generate_import_node(package, name), Newline()]),
                                              Leaf(token.DEDENT, '')])])

    # We can just hardcode the correct insert position since we just created the typing block
    root.insert_child(insert_pos, type_check_node)
    # Make sure to import TYPE_CHECKING just before using
    import_type_checking = [_generate_import_node('typing', 'TYPE_CHECKING'), Newline()]
    root.insert_child(insert_pos, Node(syms.simple_stmt, import_type_checking))
示例#6
0
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])
示例#7
0
def _generate_import_node(package, name, prefix=""):

    def DottedName(name, prefix=""):
        split = name.rsplit('.')
        if len(split) > 1:
            # Reconstruct the dotted name as a list of leaves
            leftmost_name = Leaf(token.NAME, split[0])
            children = [leftmost_name]
            for entry in split[1:]:
                next_name = [Leaf(token.DOT, '.'), Leaf(token.NAME, entry)]
                children.extend(next_name)
            return Node(syms.dotted_name, children, prefix=prefix)
        return Leaf(token.NAME, name, prefix=prefix)

    if not package:
        import_ = Node(syms.import_name, [
            Leaf(token.NAME, "import", prefix=prefix),
            DottedName(name, prefix=" ")
        ])
    else:
        import_ = Node(syms.import_from, [
            Leaf(token.NAME, "from", prefix=prefix),
            DottedName(package, prefix=" "),
            Leaf(token.NAME, "import", prefix=" "),
            Leaf(token.NAME, name, prefix=" "),
        ])

    return import_
示例#8
0
def RaisesRegexOp(context, designator, exceptionClass, expected_regex,
                  indent, kws, arglist):
    arglist = [a.clone() for a in arglist.children]
    del arglist[2:4] # remove pattern and comma
    arglist = Node(syms.arglist, arglist)
    with_stmt = RaisesOp(context, exceptionClass, indent, kws, arglist)
    with_stmt.insert_child(2, Name('as', prefix=" "))
    with_stmt.insert_child(3, Name(designator, prefix=" "))
    return Node(syms.suite,
                [with_stmt,
                 Newline(),
                 Name('assert re.search(pattern, %s.value)' % designator,
                      prefix=indent)
                 ])
def add_import(import_name, node):
    suite = get_parent_of_type(node, syms.suite)
    test_case = suite
    while test_case.parent.type != syms.file_input:
        test_case = test_case.parent
    file_input = test_case.parent

    if not does_tree_import(None, import_name, node):
        import_stmt = Node(syms.simple_stmt, [
            Node(
                syms.import_name,
                [Name('import'), Name(import_name, prefix=' ')]),
            Newline(),
        ])
        insert_import(import_stmt, test_case, file_input)
示例#10
0
 def handle_name(name, prefix):
     if name.type == syms.import_as_name:
         kids = [Name(name.children[0].value, prefix=prefix),
                 name.children[1].clone(),
                 name.children[2].clone()]
         return [Node(syms.import_as_name, kids)]
     return [Name(name.value, prefix=prefix)]
示例#11
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))
    def match(self, node):
        u"""
        Since the tree needs to be fixed once and only once if and only if it
        matches, we can start discarding matches after the first.
        """
        if node.type == self.syms.term:
            matched = False
            skip = False
            children = []
            for child in node.children:
                if skip:
                    skip = False
                    continue
                if match_division(child) and not is_floaty(child):
                    matched = True

                    # Strip any leading space for the first number:
                    children[0].prefix = u''

                    children = [
                        wrap_in_fn_call(
                            "old_div",
                            children +
                            [Comma(), child.next_sibling.clone()],
                            prefix=node.prefix)
                    ]
                    skip = True
                else:
                    children.append(child.clone())
            if matched:
                return Node(node.type,
                            children,
                            fixers_applied=node.fixers_applied)

        return False
示例#13
0
    def transform(self, node: LN, capture: Capture) -> None:
        full_name = []
        trailer: List[LN] = []
        for i, n in enumerate(node.children):
            if n.type == token.NAME:
                full_name.append(n.value)
            elif n.type == syms.trailer:
                if n.children[0].type != token.DOT:
                    trailer = node.children[i:]
                    break
                full_name.append(n.children[1].value)
            else:
                trailer = node.children[i:]

        try:
            new_name = self.renames.get_new_name(".".join(full_name))
        except NameRemovedError as exc:
            self.warn(node, str(exc))
            return

        if new_name:
            new_node = Node(syms.power,
                            AttrChain(new_name),
                            prefix=node.prefix)
            for n in trailer:
                new_node.append_child(n)
            node.replace(new_node)
示例#14
0
def Import(name_leafs):

    for leaf in name_leafs:
        # Pull the leaves out of their old tree
        leaf.remove()

    def add_commas(leafs):
        yield leafs[0]
        for a in leafs[1:]:
            yield Comma()
            yield a

    children = [Leaf(token.NAME, u'import'),
                Node(syms.dotted_as_names, list(add_commas(name_leafs)))]
    imp = Node(syms.import_name, children)
    return imp
示例#15
0
 def transform(self, node, results):
     FIXME
     name, val, trc = (
         results.get(u"name"),
         results.get(u"val"),
         results.get(u"trc"),
     )
     chain = results.get(u"chain")
     if chain is not None:
         self.warning(
             node,
             u"explicit exception chaining is not supported in Python 2")
         chain.prev_sibling.remove()
         chain.remove()
     if trc is not None:
         val = val[0] if val else Leaf(token.NAME, u"None")
         val.prefix = trc.prefix = u" "
         kids = [
             Leaf(token.NAME, u"raise"),
             name.clone(),
             Comma(),
             val.clone(),
             Comma(),
             trc.clone(),
         ]
         raise_stmt = Node(syms.raise_stmt, kids)
         node.replace(raise_stmt)
示例#16
0
    def transform(self, node, results):
        meta_results = has_metaclass(node)
        if not meta_results: return
        for meta in meta_results:
            meta.remove()
        target = Leaf(token.NAME, u"__metaclass__")
        equal = Leaf(token.EQUAL, u"=", prefix=u" ")
        # meta is the last item in what was returned by has_metaclass(): name
        name = meta
        name.prefix = u" "
        stmt_node = Node(syms.atom, [target, equal, name])

        suitify(node)
        for item in node.children:
            if item.type == syms.suite:
                for stmt in item.children:
                    if stmt.type == token.INDENT:
                        # Insert, in reverse order, the statement, a newline,
                        # and an indent right after the first indented line
                        loc = item.children.index(stmt) + 1
                        # Keep consistent indentation form
                        ident = Leaf(token.INDENT, stmt.value)
                        item.insert_child(loc, ident)
                        item.insert_child(loc, Newline())
                        item.insert_child(loc, stmt_node)
                        break
def RaisesOp(context, exceptionClass, indent, kws, arglist, node):
    exceptionClass.prefix = ""
    args = [exceptionClass]
    # Add match keyword arg to with statement if an expected regex was provided.
    # In py27 the keyword is `expected_regexp`, in py3 is `expected_regex`
    if 'expected_regex' in kws or 'expected_regexp' in kws:
        expected_regex = kws.get('expected_regex',
                                 kws.get('expected_regexp')).clone()
        expected_regex.prefix = ''
        args.append(String(', '))
        args.append(KeywordArg(Name('match'), expected_regex))
    with_item = Call(Name(context), args)
    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:
        # TODO: Newlines within arguments are not handled yet.
        # If argment prefix contains a newline, all whitespace around this
        # ought to be replaced by indent plus 4+1+len(func) spaces.
        suite = Call(func, arglist)

    suite.prefix = indent + (4 * " ")
    return Node(
        syms.with_stmt,
        [Name('with'), with_item,
         Name(':'), Newline(), suite])
示例#18
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
示例#19
0
def ImportAsName(name: str, nick: Optional[str], prefix: Optional[str] = None) -> Node:
    if not nick:
        return Name(name, prefix=prefix)
    return Node(
        syms.import_as_name,
        [Name(name), Name("as", prefix=" "), Name(nick, prefix=" ")],
        prefix=prefix,
    )
def CompOp(op, left, right, kws):
    op = Name(op, prefix=" ")
    left = parenthesize_expression(left)
    right = parenthesize_expression(right)

    left.prefix = ""
    if '\n' not in right.prefix:
        right.prefix = " "
    return Node(syms.comparison, (left, op, right), prefix=" ")
 def transform(self, node, result):
     if len(node.children) == 3 and node.children[-1].type == token.NUMBER:
         userdata_id = int(node.children[-1].value)
         replacement = self.subfun(userdata_id)
         if replacement:
             new = Node(python_symbols.subscriptlist,
                        [Leaf(token.NAME, replacement)])
             return new
     return None
示例#22
0
def UnaryOp(prefix, postfix, value, kws):
    kids = []
    if prefix:
        kids.append(Name(prefix, prefix=" "))
    value.prefix = " "
    kids.append(value)
    if postfix:
        kids.append(Name(postfix, prefix=" "))
    return Node(syms.test, kids, prefix=" ")
def RaisesRegexOp(context, designator, exceptionClass, expected_regex, indent,
                  kws, arglist, node):
    arglist = [a.clone() for a in arglist.children]
    pattern = arglist[2]
    del arglist[2:4]  # remove pattern and comma
    arglist = Node(syms.arglist, arglist)
    with_stmt = RaisesOp(context, exceptionClass, indent, kws, arglist, node)

    # if this is already part of a with statement we need to insert re.search
    # after the last leaf with content
    if node.parent.type == syms.with_stmt:
        parent_with = node.parent
        for leaf in reversed(list(parent_with.leaves())):
            if leaf.value.strip():
                break
        i = leaf.parent.children.index(leaf)
        return with_stmt
    else:
        return Node(syms.suite, [with_stmt])
示例#24
0
def DottedName(full_name: str, prefix: Optional[str]) -> Node:
    names = [name.strip() for name in full_name.split(".")]

    dotted_name = []
    for name in names:
        dotted_name.append(Name(name))
        dotted_name.append(Dot())
    dotted_name.pop()

    return Node(syms.dotted_name, dotted_name, prefix=prefix)
示例#25
0
def FromImport(
    package: str, imports: List[Tuple[str, Optional[str]]], prefix: Optional[str]
) -> Node:
    children = []
    for name, nick in imports:
        children.append(ImportAsName(name, nick, prefix=" "))
        children.append(Comma())
    children.pop()
    import_as_names = Node(syms.import_as_names, children)

    return Node(
        syms.import_from,
        [
            Name("from", prefix=prefix),
            DottedName(package, prefix=" "),
            Name("import", prefix=" "),
            import_as_names,
        ],
    )
示例#26
0
 def DottedName(name, prefix=""):
     split = name.rsplit('.')
     if len(split) > 1:
         # Reconstruct the dotted name as a list of leaves
         leftmost_name = Leaf(token.NAME, split[0])
         children = [leftmost_name]
         for entry in split[1:]:
             next_name = [Leaf(token.DOT, '.'), Leaf(token.NAME, entry)]
             children.extend(next_name)
         return Node(syms.dotted_name, children, prefix=prefix)
     return Leaf(token.NAME, name, prefix=prefix)
示例#27
0
    def transform(self, node, results):

        def process_arg(arg):
            if isinstance(arg, Leaf) and arg.type == token.COMMA:
                return
            elif isinstance(arg, Node) and arg.type == syms.argument:
                # keyword argument
                name, equal, value = arg.children
                assert name.type == token.NAME # what is the symbol for 1?
                assert equal.type == token.EQUAL # what is the symbol for 1?
                value = value.clone()
                value.prefix = " "
                kwargs[name.value] = value
            else:
                assert not kwargs, 'all positional args are assumed to come first'
                posargs.append(arg.clone())

        method = results['method'][0].value
        # map (deprecated) aliases to original to avoid analysing
        # the decorator function
        method = _method_aliases.get(method, method)

        posargs = []
        kwargs = {}

        # This is either a "arglist" or a single argument
        if results['arglist'].type == syms.arglist:
            for arg in results['arglist'].children:
                process_arg(arg)
        else:
            process_arg(results['arglist'])

        try:
            test_func = getattr(unittest.TestCase, method)
        except AttributeError:
            raise RuntimeError("Your unittest package does not support '%s'. "
                               "consider updating the package" % method)

        required_args, argsdict = utils.resolve_func_args(test_func, posargs, kwargs)

        if method.startswith(('assertRaises', 'assertWarns')):
            n_stmt = _method_map[method](*required_args,
                                         indent=find_indentation(node),
                                         kws=argsdict,
                                         arglist=results['arglist'])
        else:
            n_stmt = Node(syms.assert_stmt,
                          [Name('assert'),
                           _method_map[method](*required_args, kws=argsdict)])
        if argsdict.get('msg', None) is not None:
            n_stmt.children.extend((Name(','), argsdict['msg']))
        n_stmt.prefix = node.prefix

        return n_stmt
def UnaryOp(prefix, postfix, value, kws):
    if prefix or postfix:
        value = parenthesize_expression(value)

    kids = []
    if prefix:
        kids.append(Name(prefix, prefix=" "))
    value.prefix = " "
    kids.append(value)
    if postfix:
        kids.append(Name(postfix, prefix=" "))
    return Node(syms.test, kids, prefix=" ")
    def match(self, node):
        u"""
        Since the tree needs to be fixed once and only once if and only if it
        matches, we can start discarding matches after the first.
        """
        if node.type == self.syms.term:
            matched = False
            skip = False
            children = []
            for child in node.children:
                if skip:
                    skip = False
                    continue
                if match_division(child) and not is_floaty(child):
                    matched = True

                    # Strip any leading space for the first number:
                    children[0].prefix = u''

                    children = [
                        wrap_in_fn_call(
                            "old_div",
                            children +
                            [Comma(), child.next_sibling.clone()],
                            prefix=node.prefix)
                    ]
                    skip = True
                else:
                    children.append(child.clone())
            if matched:
                # In Python 2.6, `Node` does not have the fixers_applied attribute
                # https://github.com/python/cpython/blob/8493c0cd66cfc181ac1517268a74f077e9998701/Lib/lib2to3/pytree.py#L235
                if hasattr(Node, "fixers_applied"):
                    return Node(node.type,
                                children,
                                fixers_applied=node.fixers_applied)
                else:
                    return Node(node.type, children)

        return False
示例#30
0
def fixup_simple_stmt(parent, i, stmt_node):
    """ if there is a semi-colon all the parts count as part of the same
        simple_stmt.  We just want the __metaclass__ part so we move
        everything efter the semi-colon into its own simple_stmt node
    """
    for semi_ind, node in enumerate(stmt_node.children):
        if node.type == token.SEMI:  # *sigh*
            break
    else:
        return

    node.remove()  # kill the semicolon
    new_expr = Node(syms.expr_stmt, [])
    new_stmt = Node(syms.simple_stmt, [new_expr])
    while stmt_node.children[semi_ind:]:
        move_node = stmt_node.children[semi_ind]
        new_expr.append_child(move_node.clone())
        move_node.remove()
    parent.insert_child(i, new_stmt)
    new_leaf1 = new_stmt.children[0].children[0]
    old_leaf1 = stmt_node.children[0].children[0]
    new_leaf1.prefix = old_leaf1.prefix