Ejemplo n.º 1
0
 def _api_rename(node: LN, capture: Capture, filename: Filename):
     code = ''
     for leaf in node.leaves():
         code = code + leaf.value
     found_rename = False
     found_warning = False
     api = None
     for _api in rename_map.keys():
         if utils.startswith(code, _api):
             found_rename = True
             api = _api
             break
     for _api in warning_map.keys():
         if utils.startswith(code, _api):
             found_warning = True
             api = _api
             break
     if not found_rename and not found_warning:
         return
     # if found rename, replace old_api with new_api
     if found_rename:
         utils.replace_module_path(node, api, rename_map[api])
     # if not found rename and found warning, print warning
     elif found_warning:
         log_warning(filename, node.get_lineno(), warning_map[api])
Ejemplo n.º 2
0
    def _full_module_path(node: LN, capture: Capture, filename: Filename):
        if not (isinstance(node, Leaf) and node.type == token.NAME):
            return
        if filename not in imports_map:
            return
        logger.debug("{} [{}]: {}".format(filename, list(capture), node))

        # skip import statement
        if utils.is_import_node(node):
            return
        # skip left operand in argument list
        if utils.is_argument_node(node) and utils.is_left_operand(node):
            return
        # skip if it's already a full module path
        if node.prev_sibling is not None and node.prev_sibling.type == token.DOT:
            return

        rename_dict = imports_map[filename]
        if node.value in rename_dict:
            # find old_name and new_name
            old_name = node.value
            new_name = rename_dict[old_name]
            if node.parent is not None:
                _node = utils.code_repr(new_name).children[0].children[0]
                _node.parent = None
                new_node = _node
                new_node.children[0].prefix = node.prefix
                if node.parent.type == python_symbols.power:
                    node.replace(new_node.children)
                else:
                    node.replace(new_node)
                log_info(
                    filename, node.get_lineno(),
                    "{} -> {}".format(utils.node2code(node),
                                      utils.node2code(new_node)))
Ejemplo n.º 3
0
 def _add_import(node: LN, capture: Capture, filename: Filename):
     if node.type != python_symbols.file_input:
         return
     if filename in paddle_imported:
         return
     if filename in paddle_found:
         touch_import(None, 'paddle', node, force=True)
         log_info(filename, node.get_lineno(), 'add "import paddle"')
         paddle_imported.add(filename)
Ejemplo n.º 4
0
 def _norm(node: LN, capture: Capture, filename: Filename):
     code = ''
     for leaf in node.leaves():
         code = code + leaf.value
     found_alias = False
     alias = None
     for _alias in alias_map.keys():
         if utils.startswith(code, _alias):
             found_alias = True
             alias = _alias
             break
     if not found_alias:
         return
     main_alias = alias_map[alias]
     update_to = change_spec[main_alias].get('update_to', None)
     # if main_alias contains "update_to" field, rename alias to "update_to" directly
     utils.replace_module_path(node, alias, main_alias)
     log_info(filename, node.get_lineno(),
              '{} -> {}'.format(alias, main_alias))
Ejemplo n.º 5
0
def print_node(node: LN,
               max_depth: int = 1000,
               indent: str = "",
               last: bool = True,
               capture={}):
    """Debugging function to print node tree.
    Arguments:
        node: The node to print
        max_depth: The maximum recursion depth to walk children
    """
    if last:
        first_i = "└─"
        second_i = "  "
    else:
        first_i = "├─"
        second_i = "│ "
    prefix = indent + first_i
    name = ""
    if node in capture.values():
        name = ("\033[32m" + next(k for k, v in capture.items() if v == node) +
                "\033[0m= ")
    if type(node) is Node:
        print(prefix + name + "Node[{}] prefix={} suffix={}".format(
            type_repr(node.type), repr(node.prefix), repr(node.get_suffix())))
    elif type(node) is Leaf:
        print(indent + first_i + name + "Leaf({}, {}, col={}{})".format(
            token.tok_name[node.type],
            repr(node.value),
            node.column,
            ", prefix={}".format(repr(node.prefix)) if node.prefix else "",
        ))
    else:
        raise RuntimeError("Unknown node type")
    indent = indent + second_i

    children = list(node.children)
    if max_depth == 0 and children:
        print(indent + f"└─...{len(children)} children")
    else:
        for i, child in enumerate(node.children):
            print_node(
                child,
                indent=indent,
                last=(i + 1) == len(children),
                max_depth=max_depth - 1,
                capture=capture,
            )
Ejemplo n.º 6
0
    def _remove_with_dygraph_guard(node: LN, capture: Capture,
                                   filename: Filename):
        # index of with_node, with_node will be replaced with simple_stmt node
        with_node = capture['with']
        parent = with_node.parent
        idx = None
        for i, child in enumerate(parent.children):
            if child is with_node:
                idx = i
                break

        # create simple_stmt node for "paddle.disable_static"
        arg_list_nodes = capture['arg_list']
        simple_stmt_disable_static = Node(python_symbols.simple_stmt,
                                          [utils.newline_node(node)])
        _node = utils.code_repr('paddle.disable_static' +
                                str(arg_list_nodes)).children[0].children[0]
        _node.parent = None
        simple_stmt_disable_static.insert_child(0, _node)
        simple_stmt_disable_static.prefix = with_node.prefix

        # create simple_stmt node for "paddle.enable_static"
        simple_stmt_enable_static = Node(python_symbols.simple_stmt,
                                         [utils.newline_node(node)])
        simple_stmt_enable_static
        _node = utils.code_repr(
            'paddle.enable_static()').children[0].children[0]
        _node.parent = None
        simple_stmt_enable_static.insert_child(0, _node)
        simple_stmt_enable_static.prefix = utils.get_indent(with_node)

        suite_node = capture['suite']
        # remove first newline
        for node in suite_node.children:
            if not isinstance(node, Leaf):
                continue
            if node.type == token.NEWLINE:
                node.remove()
                break
        # remove first indent node, and add indent prefix to sibling node.
        indent = None
        for node in suite_node.children:
            if not isinstance(node, Leaf):
                continue
            if node.type == token.INDENT:
                indent = node.value
                if node.next_sibling is not None:
                    node.next_sibling.prefix = node.prefix + indent
                node.remove()
                break

        # transfer post leading dedent node prefix to sibling of with node
        leaves = [leaf for leaf in suite_node.leaves()]
        # visit all leaves in reversed order
        last_dedent_leaf_idx = len(leaves)
        for leaf in leaves[::-1]:
            if leaf.type == token.DEDENT:
                with_node.next_sibling.prefix = leaf.prefix + with_node.next_sibling.prefix
                leaf.prefix = ""
            else:
                break

        # remove dedenet node corresponding to with node
        for node in suite_node.children[::-1]:
            if not isinstance(node, Leaf):
                continue
            if node.type == token.DEDENT:
                node.remove()
                break

        # unindent all code in suite
        for node in suite_node.leaves():
            if node.type == token.INDENT:
                node.value = utils.dec_indent(node.value)
            else:
                node.prefix = utils.dec_indent(node.prefix)

        with_node.remove()
        parent.insert_child(idx, simple_stmt_disable_static)
        idx += 1
        for node in suite_node.children:
            parent.insert_child(idx, node)
            idx += 1
        parent.insert_child(idx, simple_stmt_enable_static)
Ejemplo n.º 7
0
def process_import(node: LN, capture: Capture,
                   filename: Filename) -> Optional[LN]:
    # Skip any imports at file scope
    if node.parent.parent.type == python_symbols.file_input:
        return

    IMPORT_WHITELIST = {
        "importlib",
        "math",
        "optparse",
        "os",
        "os.path",
        "six.moves.cPickle as pickle",
        "six.moves",
        "sys",
        "urllib2",
        "uuid",
    }
    module_name = str(node.children[1]).strip()

    always_float = module_name in IMPORT_WHITELIST
    # if STDLIB_ONLY:
    #     if :
    #         return
    # See if this is rejected
    if ONLY_FLOAT:
        isort_class = None
        if any(x.isupper() for x in ONLY_FLOAT):
            isort_class = isort.place_module(
                module_name, config=get_isort_config_for(filename))
        if (module_name not in ONLY_FLOAT and
                not any(module_name.startswith(x + ".") for x in ONLY_FLOAT)
                and isort_class not in ONLY_FLOAT):
            return

    # if not always_float:
    # Bypass nodes with comments for now
    if node.get_suffix().strip() or get_complete_prefix(node).strip():
        print(
            f"Not floating {filename}:{node.get_lineno()} ({module_name}) as has comments"
        )
        return

    if "matplotlib" in str(node):
        print(f"Not floating {filename}:{node.get_lineno()} as matplotlib")
        return

    # Find the root node. While doing so, check that we aren't inside a try
    root = node
    while root.parent:
        # Handle always-float and try blocks - don't leave invalid
        if root.type == python_symbols.try_stmt:
            if always_float:
                # Check that we aren't the only entry in this suite
                assert node.parent.parent.type == python_symbols.suite
                if len(node.parent.parent.children) == 4:
                    print(
                        f"Not floating always-float {filename}:{node.get_lineno()} ({module_name}) as only statement inside try"
                    )
                    return
            else:
                print(
                    f"Not floating {filename}:{node.get_lineno()} ({module_name}) as inside try"
                )
                return
        if not always_float:
            # Give a special message to the user for __main__ if non-floating
            if (root.type == python_symbols.if_stmt and not IGNORE_IF
                    and "__main__" in str(root.children[1])):
                print(
                    f"Not floating {filename}:{node.get_lineno()} ({module_name}) as inside __main__ test if"
                )
                return
            if root.type == python_symbols.if_stmt and not IGNORE_IF:
                print(
                    f"Not floating {filename}:{node.get_lineno()} ({module_name}) as inside if"
                )
                return

        root = root.parent

    # Find the insertion point for this root node
    insert_point = find_import_insert_point(root)

    # Get the actual statement node
    statement = node.parent
    prev_sibling = statement.prev_sibling
    next_sibling = statement.next_sibling
    assert statement.type == python_symbols.simple_stmt

    # Are we are the start of a scope?
    parent_index = statement.parent.children.index(statement)
    # From suite definition; parent_index of first statement is either 0 or 2:
    #   suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT
    # But for our purposes can be 3 if we have a docstring.
    assert parent_index != 0, "Inline statement functions not supported ATM"
    prev_sibiling_is_string = (prev_sibling.type == python_symbols.simple_stmt
                               and prev_sibling.children[0].type
                               == token.STRING)
    if parent_index == 2 or (parent_index == 3 and prev_sibiling_is_string):
        # We're the first statement, or the first non-docstring statement.
        # If we have a trailing newline, remove it. Indentation handled later.
        if next_sibling and next_sibling.prefix.startswith("\n"):
            next_sibling.prefix = next_sibling.prefix[1:]

    # Get the previous node. This might be the sibling, or some tree-child thereof
    prev_node = list(prev_sibling.leaves())[-1]

    # print_node(prev_node)
    if prev_node.type in {token.INDENT, token.DEDENT}:
        # If we just indented(dedented) then tree looks like:
        #   [INDENT]      "    "
        #   [simple_stmt] ""            <- statement
        #       ...
        #       [NEWLINE] ""      "\n"
        #   [LN]          "    "
        # e.g. this next sibling node holds it's own indent but the
        # statement node's indentation is handled by the indent. So we
        # need to remove the indentation from the next sibling.
        next_sibling.prefix = next_sibling.prefix.lstrip(" ")

    if prev_node.type == token.INDENT and prev_node.prefix.isspace():
        # We've got leading newlines we want to strip -
        # If a function starts with a blank line(s), the "\n" and any
        # stray indentation are attached to the [INDENT] as a prefix.
        # Our reasoning for removing this blank line: It was showing the
        # user that the import was special.
        # This might be flimsy reasoning.
        prev_node.prefix = ""

    # We could be transplanting a node with a prefix. Move it to the sibling
    next_sibling.prefix = node.prefix.rstrip(" ") + next_sibling.prefix

    # Do the actual moving
    statement.remove()
    root.insert_child(insert_point, statement)
    node.prefix = ""