Esempio n. 1
0
 def visit_nodelist(self, nodelist):
     for i in range(len(nodelist)):
         node = nodelist[i]
         if isinstance(node, gast.If):
             true_branch_returns = isinstance(node.body[-1], gast.Return)
             false_branch_returns = len(node.orelse) and isinstance(
                 node.orelse[-1], gast.Return)
             # If the last node in the if body is a return,
             # then every line after this if statement effectively
             # belongs in the else.
             if true_branch_returns and not false_branch_returns:
                 for j in range(i + 1, len(nodelist)):
                     nodelist[i].orelse.append(
                         ast_util.copy_clean(nodelist[j]))
                 if nodelist[i + 1:]:
                     self.changes_made = True
                 return nodelist[:i + 1]
             elif not true_branch_returns and false_branch_returns:
                 for j in range(i + 1, len(nodelist)):
                     nodelist[i].body.append(
                         ast_util.copy_clean(nodelist[j]))
                 if nodelist[i + 1:]:
                     self.changes_made = True
                 return nodelist[:i + 1]
             elif true_branch_returns and false_branch_returns:
                 if nodelist[i + 1:]:
                     raise ValueError(
                         'Unreachable code after conditional where both branches return.'
                     )
                 return nodelist
         elif isinstance(node, gast.Return) and nodelist[i + 1:]:
             raise ValueError(
                 'Cannot have statements after a return in the same basic block'
             )
     return nodelist
 def visit_nodelist(self, nodelist):
   for i in range(len(nodelist)):
     node = nodelist[i]
     if isinstance(node, gast.If):
       true_branch_returns = isinstance(node.body[-1], gast.Return)
       false_branch_returns = len(node.orelse) and isinstance(
           node.orelse[-1], gast.Return)
       # If the last node in the if body is a return,
       # then every line after this if statement effectively
       # belongs in the else.
       if true_branch_returns and not false_branch_returns:
         for j in range(i + 1, len(nodelist)):
           nodelist[i].orelse.append(ast_util.copy_clean(nodelist[j]))
         if nodelist[i + 1:]:
           self.changes_made = True
         return nodelist[:i + 1]
       elif not true_branch_returns and false_branch_returns:
         for j in range(i + 1, len(nodelist)):
           nodelist[i].body.append(ast_util.copy_clean(nodelist[j]))
         if nodelist[i + 1:]:
           self.changes_made = True
         return nodelist[:i + 1]
       elif true_branch_returns and false_branch_returns:
         if nodelist[i + 1:]:
           raise ValueError(
               'Unreachable code after conditional where both branches return.'
           )
         return nodelist
     elif isinstance(node, gast.Return) and nodelist[i + 1:]:
       raise ValueError(
           'Cannot have statements after a return in the same basic block')
   return nodelist
Esempio n. 3
0
 def test_copy_clean_preserves_annotations(self):
   node = parser.parse_str(
       textwrap.dedent("""
     def f(a):
       return a + 1
   """))
   anno.setanno(node.body[0], 'foo', 'bar')
   anno.setanno(node.body[0], 'baz', 1)
   new_node = ast_util.copy_clean(node, preserve_annos={'foo'})
   self.assertEqual(anno.getanno(new_node.body[0], 'foo'), 'bar')
   self.assertFalse(anno.hasanno(new_node.body[0], 'baz'))
Esempio n. 4
0
 def test_copy_clean(self):
   node = parser.parse_str(
       textwrap.dedent("""
     def f(a):
       return a + 1
   """))
   setattr(node.body[0], '__foo', 'bar')
   new_node = ast_util.copy_clean(node)
   self.assertIsNot(new_node, node)
   self.assertIsNot(new_node.body[0], node.body[0])
   self.assertFalse(hasattr(new_node.body[0], '__foo'))
Esempio n. 5
0
 def test_copy_clean_preserves_annotations(self):
     node = parser.parse_str(
         textwrap.dedent("""
   def f(a):
     return a + 1
 """))
     anno.setanno(node.body[0], 'foo', 'bar')
     anno.setanno(node.body[0], 'baz', 1)
     new_node = ast_util.copy_clean(node, preserve_annos={'foo'})
     self.assertEqual(anno.getanno(new_node.body[0], 'foo'), 'bar')
     self.assertFalse(anno.hasanno(new_node.body[0], 'baz'))
Esempio n. 6
0
 def test_copy_clean(self):
     node = parser.parse_str(
         textwrap.dedent("""
   def f(a):
     return a + 1
 """))
     setattr(node.body[0], '__foo', 'bar')
     new_node = ast_util.copy_clean(node)
     self.assertIsNot(new_node, node)
     self.assertIsNot(new_node.body[0], node.body[0])
     self.assertFalse(hasattr(new_node.body[0], '__foo'))
Esempio n. 7
0
  def _prepare_replacement(self, replaced, key):
    """Prepares a replacement AST that's safe to swap in for a node.

    Args:
      replaced: ast.AST, the node being replaced
      key: Hashable, the key of the replacement AST
    Returns:
      ast.AST, the replacement AST
    """
    repl = self.replacements[key]

    new_nodes = ast_util.copy_clean(repl, preserve_annos=self.preserved_annos)
    if isinstance(new_nodes, gast.AST):
      new_nodes = [new_nodes]

    return new_nodes
Esempio n. 8
0
  def _prepare_replacement(self, replaced, key):
    """Prepares a replacement AST that's safe to swap in for a node.

    Args:
      replaced: ast.AST, the node being replaced
      key: Hashable, the key of the replacement AST
    Returns:
      ast.AST, the replacement AST
    """
    repl = self.replacements[key]

    new_nodes = ast_util.copy_clean(repl, preserve_annos=self.preserved_annos)
    if isinstance(new_nodes, gast.AST):
      new_nodes = [new_nodes]

    return new_nodes
Esempio n. 9
0
 def test_copy_clean(self):
     ret = ast.Return(
         ast.BinOp(op=ast.Add(),
                   left=ast.Name(id='a', ctx=ast.Load()),
                   right=ast.Num(1)))
     setattr(ret, '__foo', 'bar')
     node = ast.FunctionDef(name='f',
                            args=ast.arguments(
                                args=[ast.Name(id='a', ctx=ast.Param())],
                                vararg=None,
                                kwarg=None,
                                defaults=[]),
                            body=[ret],
                            decorator_list=[],
                            returns=None)
     new_node = ast_util.copy_clean(node)
     self.assertFalse(node is new_node)
     self.assertFalse(ret is new_node.body[0])
     self.assertFalse(hasattr(new_node.body[0], '__foo'))
Esempio n. 10
0
 def test_copy_clean(self):
   ret = ast.Return(
       ast.BinOp(
           op=ast.Add(),
           left=ast.Name(id='a', ctx=ast.Load()),
           right=ast.Num(1)))
   setattr(ret, '__foo', 'bar')
   node = ast.FunctionDef(
       name='f',
       args=ast.arguments(
           args=[ast.Name(id='a', ctx=ast.Param())],
           vararg=None,
           kwarg=None,
           defaults=[]),
       body=[ret],
       decorator_list=[],
       returns=None)
   new_node = ast_util.copy_clean(node)
   self.assertFalse(node is new_node)
   self.assertFalse(ret is new_node.body[0])
   self.assertFalse(hasattr(new_node.body[0], '__foo'))
Esempio n. 11
0
    def visit_Name(self, node):
        if node.id not in self.replacements:
            return node

        new_nodes = ast_util.copy_clean(self.replacements[node.id])
        if isinstance(new_nodes, gast.AST):
            new_nodes = [new_nodes]

        # Preserve the target context.
        for n in new_nodes:
            if isinstance(n, gast.Tuple):
                for e in n.elts:
                    self._set_inner_child_context(e, node.ctx)
            if isinstance(n, gast.Attribute):
                # For attributes, the inner Name node receives the context, while the
                # outer ones have it set to Load.
                self._set_inner_child_context(n, node.ctx)
            else:
                n.ctx = node.ctx

        if len(new_nodes) == 1:
            new_nodes, = new_nodes

        return new_nodes
Esempio n. 12
0
  def visit_Name(self, node):
    if node.id not in self.replacements:
      return node

    new_nodes = ast_util.copy_clean(self.replacements[node.id])
    if isinstance(new_nodes, gast.AST):
      new_nodes = [new_nodes]

    # Preserve the target context.
    for n in new_nodes:
      if isinstance(n, gast.Tuple):
        for e in n.elts:
          self._set_inner_child_context(e, node.ctx)
      if isinstance(n, gast.Attribute):
        # For attributes, the inner Name node receives the context, while the
        # outer ones have it set to Load.
        self._set_inner_child_context(n, node.ctx)
      else:
        n.ctx = node.ctx

    if len(new_nodes) == 1:
      new_nodes, = new_nodes

    return new_nodes