Beispiel #1
0
def _rename_reads(sc, t, old_name, new_name):
    """Updates all locations in the module where the given name is read.

  Arguments:
    sc: (scope.Scope) Scope to work in. This should be the scope of `t`.
    t: (ast.AST) The AST to perform updates in.
    old_name: (string) Dotted name to update.
    new_name: (string) Dotted name to replace it with.

  Returns:
    True if any changes were made, False otherwise.
  """
    name_parts = old_name.split('.')
    try:
        name = sc.names[name_parts[0]]
        for part in name_parts[1:]:
            name = name.attrs[part]
    except KeyError:
        return False

    has_changed = False
    for ref_node in name.reads:
        if isinstance(ref_node, (ast.Name, ast.Attribute)):
            ast_utils.replace_child(sc.parent(ref_node), ref_node,
                                    ast.parse(new_name).body[0].value)
            has_changed = True
        elif isinstance(ref_node, ast.Str) and ref_node.s.startswith(old_name):
            ref_node.s = ref_node.s.replace(old_name, new_name, 1)

    return has_changed
Beispiel #2
0
        def testReplaceChildInvalid(self):
            src = 'def foo():\n  return 1\nx = 1\n'
            replace_with = pasta.parse('bar()', py_ver).body[0]
            t = pasta.parse(src, py_ver)

            parent = t.body[0]
            node_to_replace = t.body[1]
            with self.assertRaises(errors.InvalidAstError):
                ast_utils.replace_child(parent, node_to_replace, replace_with)
Beispiel #3
0
    def testReplaceChildInBody(self):
        src = 'def foo():\n  a = 0\n  a += 1 # replace this\n  return a\n'
        replace_with = pasta.parse('foo(a + 1)  # trailing comment\n').body[0]
        expected = 'def foo():\n  a = 0\n  foo(a + 1) # replace this\n  return a\n'
        t = pasta.parse(src)

        parent = t.body[0]
        node_to_replace = parent.body[1]
        ast_utils.replace_child(parent, node_to_replace, replace_with)

        self.assertEqual(expected, pasta.dump(t))
Beispiel #4
0
def inline_name(t, name, py_ver=sys.version_info[:2]):
    """Inline a constant name into a module."""
    sc = scope.analyze(t)
    name_node = sc.names[name]

    # The name must be a Name node (not a FunctionDef, etc.)
    if not isinstance(name_node.definition, (ast27.Name, ast3.Name)):
        raise InlineError('%r is not a constant; it has type %r' %
                          (name, type(name_node.definition)))

    assign_node = sc.parent(name_node.definition)
    if not isinstance(assign_node, (ast27.Assign, ast3.Assign)):
        raise InlineError('%r is not declared in an assignment' % name)

    value = assign_node.value
    if not isinstance(sc.parent(assign_node), (ast27.Module, ast3.Module)):
        raise InlineError('%r is not a top-level name' % name)

    # If the name is written anywhere else in this module, it is not constant
    for ref in name_node.reads:
        if isinstance(getattr(ref, 'ctx', None), (ast27.Store, ast3.Store)):
            raise InlineError('%r is not a constant' % name)

    # Replace all reads of the name with a copy of its value
    for ref in name_node.reads:
        ast_utils.replace_child(sc.parent(ref), ref, copy.deepcopy(value))

    # Remove the assignment to this name
    if len(assign_node.targets) == 1:
        ast_utils.remove_child(sc.parent(assign_node),
                               assign_node,
                               py_ver=py_ver)
    else:
        tgt_list = [
            tgt for tgt in assign_node.targets
            if not (isinstance(tgt, ast.Name) and tgt.id == name)
        ]
        assign_node.targets = tgt_list