예제 #1
0
 def visit_while(self, node, parent):
     """visit a While node by returning a fresh instance of it"""
     newnode = nodes.While(node.lineno, node.col_offset, parent)
     body = nodes.Block(
         'body',
         [self.visit(child, newnode) for child in node.body],
         newnode)
     orelse = nodes.Block(
         'orelse',
         [self.visit(child, newnode) for child in node.orelse],
         newnode)
     newnode.postinit(self.visit(node.test, newnode), body, orelse)
     return newnode
예제 #2
0
 def visit_tryfinally(self, node, parent):
     """visit a TryFinally node by returning a fresh instance of it"""
     newnode = nodes.TryFinally(node.lineno, node.col_offset, parent)
     body = nodes.Block(
         'body',
         [self.visit(n, newnode) for n in node.body],
         newnode)
     finalbody = nodes.Block(
         'finalbody',
         [self.visit(n, newnode) for n in node.finalbody],
         newnode)
     newnode.postinit(body, finalbody)
     return newnode
예제 #3
0
 def visit_tryexcept(self, node, parent):
     """visit a TryExcept node by returning a fresh instance of it"""
     newnode = nodes.TryExcept(node.lineno, node.col_offset, parent)
     body = nodes.Block(
         'body',
         [self.visit(child, newnode) for child in node.body],
         newnode)
     handlers = [self.visit(child, newnode) for child in node.handlers]
     orelse = nodes.Block(
         'orelse',
         [self.visit(child, newnode) for child in node.orelse],
         newnode)
     newnode.postinit(body, handlers, orelse)
     return newnode
예제 #4
0
    def _visit_functiondef(self, cls, node, parent):
        """visit an FunctionDef node to become astroid"""
        self._global_names.append({})
        node, doc = self._get_doc(node)
        newnode = cls(node.name, doc, node.lineno,
                      node.col_offset, parent)
        if node.decorator_list:
            decorators = self.visit_decorators(node, newnode)
        else:
            decorators = None
        if PY3 and node.returns:
            returns = self.visit(node.returns, newnode)
        else:
            returns = None

        type_comment_args = type_comment_returns = None
        type_comment_annotation = self.check_function_type_comment(node)
        if type_comment_annotation:
            type_comment_returns, type_comment_args = type_comment_annotation
        body = nodes.Block(
            'body',
            [self.visit(child, newnode) for child in node.body],
            newnode)
        newnode.postinit(
            args=self.visit(node.args, newnode),
            body=body,
            decorators=decorators,
            returns=returns,
            type_comment_returns=type_comment_returns,
            type_comment_args=type_comment_args,
        )
        self._global_names.pop()
        return newnode
예제 #5
0
 def visit_classdef(self, node, parent, newstyle=None):
     """visit a ClassDef node to become astroid"""
     node, doc = self._get_doc(node)
     newnode = nodes.ClassDef(node.name, doc, node.lineno,
                              node.col_offset, parent)
     metaclass = None
     if PY3:
         for keyword in node.keywords:
             if keyword.arg == 'metaclass':
                 metaclass = self.visit(keyword, newnode).value
                 break
     if node.decorator_list:
         decorators = self.visit_decorators(node, newnode)
     else:
         decorators = None
     body = nodes.Block(
         'body',
         [self.visit(child, newnode) for child in node.body],
         newnode)
     newnode.postinit([self.visit(child, newnode) for child in node.bases],
                      body,
                      decorators, newstyle, metaclass,
                      [self.visit(kwd, newnode) for kwd in node.keywords
                       if kwd.arg != 'metaclass'] if PY3 else [])
     return newnode
예제 #6
0
 def visit_if(self, node, parent):
     """visit an If node by returning a fresh instance of it"""
     newnode = nodes.If(node.lineno, node.col_offset, parent)
     body = nodes.Block(
         'body',
         [self.visit(child, newnode) for child in node.body],
         newnode)
     orelse = nodes.Block(
         'orelse',
         [self.visit(child, newnode) for child in node.orelse],
         newnode)
     has_elif_block = (
         len(node.orelse) == 1 and type(node.orelse[0]).__name__ == 'If'
         and node.orelse[0].col_offset == node.orelse[0].test.col_offset)
     newnode.postinit(
         self.visit(node.test, newnode),
         body,
         orelse,
         has_elif_block)
     return newnode
예제 #7
0
 def _visit_for(self, cls, node, parent):
     """visit a For node by returning a fresh instance of it"""
     newnode = cls(node.lineno, node.col_offset, parent)
     type_annotation = self.check_type_comment(node)
     body = nodes.Block(
         'body',
         [self.visit(child, newnode) for child in node.body],
         newnode)
     orelse = nodes.Block(
         'orelse',
         [self.visit(child, newnode) for child in node.orelse],
         newnode)
     newnode.postinit(
         target=self.visit(node.target, newnode),
         iter=self.visit(node.iter, newnode),
         body=body,
         orelse=orelse,
         type_annotation=type_annotation,
     )
     return newnode
예제 #8
0
 def visit_excepthandler(self, node, parent):
     """visit an ExceptHandler node by returning a fresh instance of it"""
     newnode = nodes.ExceptHandler(node.lineno, node.col_offset, parent)
     # /!\ node.name can be a tuple
     body = nodes.Block(
         'body',
         [self.visit(child, newnode) for child in node.body],
         newnode)
     newnode.postinit(_visit_or_none(node, 'type', self, newnode),
                      _visit_or_none(node, 'name', self, newnode),
                      body)
     return newnode
예제 #9
0
 def visit_module(self, node, modname, modpath, package):
     """visit a Module node by returning a fresh instance of it"""
     node, doc = self._get_doc(node)
     newnode = nodes.Module(name=modname, doc=doc, file=modpath,
                            path=[modpath],
                            package=package, parent=None)
     body = nodes.Block(
         'body',
         [self.visit(child, newnode) for child in node.body],
         newnode)
     newnode.postinit(body)
     return newnode
예제 #10
0
 def visit_try(self, node, parent):
     # python 3.3 introduce a new Try node replacing
     # TryFinally/TryExcept nodes
     if node.finalbody:
         newnode = nodes.TryFinally(node.lineno, node.col_offset, parent)
         if node.handlers:
             body = nodes.Block(
                 'body',
                 [self.visit_tryexcept(node, newnode)],
                 newnode)
         else:
             body = nodes.Block(
                 'body',
                 [self.visit(child, newnode) for child in node.body],
                 newnode)
         finalbody = nodes.Block(
             'finalbody',
             [self.visit(n, newnode) for n in node.finalbody],
             newnode)
         newnode.postinit(body, finalbody)
         return newnode
     elif node.handlers:
         return self.visit_tryexcept(node, parent)
     return None
예제 #11
0
 def visit_excepthandler(self, node, parent):
     """visit an ExceptHandler node by returning a fresh instance of it"""
     newnode = nodes.ExceptHandler(node.lineno, node.col_offset, parent)
     if node.name:
         name = self.visit_assignname(node, newnode, node.name)
     else:
         name = None
     body = nodes.Block(
         'body',
         [self.visit(child, newnode) for child in node.body],
         newnode)
     newnode.postinit(
         _visit_or_none(node, 'type', self, newnode),
         name,
         body)
     return newnode
예제 #12
0
    def visit_with(self, node, parent):
        newnode = nodes.With(node.lineno, node.col_offset, parent)
        expr = self.visit(node.context_expr, newnode)
        if node.optional_vars is not None:
            optional_vars = self.visit(node.optional_vars, newnode)
        else:
            optional_vars = None

        body = nodes.Block(
            'body',
            [self.visit(child, newnode) for child in node.body],
            newnode)
        type_annotation = self.check_type_comment(node)
        newnode.postinit(
            items=[(expr, optional_vars)],
            body=body,
            type_annotation=type_annotation,
        )
        return newnode
예제 #13
0
    def _visit_with(self, cls, node, parent):
        if 'items' not in node._fields:
            # python < 3.3
            return super(TreeRebuilder3, self).visit_with(node, parent)

        newnode = cls(node.lineno, node.col_offset, parent)
        def visit_child(child):
            expr = self.visit(child.context_expr, newnode)
            var = _visit_or_none(child, 'optional_vars', self, newnode)
            return expr, var

        type_annotation = self.check_type_comment(node)
        body = nodes.Block(
            'body',
            [self.visit(child, newnode) for child in node.body],
            newnode)
        newnode.postinit(
            items=[visit_child(child) for child in node.items],
            body=body,
            type_annotation=type_annotation,
        )
        return newnode
예제 #14
0
    def _infer_type_new_call(self, caller, context):
        """Try to infer what type.__new__(mcs, name, bases, attrs) returns.

        In order for such call to be valid, the metaclass needs to be
        a subtype of ``type``, the name needs to be a string, the bases
        needs to be a tuple of classes
        """
        from astroid import node_classes
        # Verify the metaclass
        mcs = next(caller.args[0].infer(context=context))
        if mcs.__class__.__name__ != 'ClassDef':
            # Not a valid first argument.
            return None
        if not mcs.is_subtype_of("%s.type" % BUILTINS):
            # Not a valid metaclass.
            return None

        # Verify the name
        name = next(caller.args[1].infer(context=context))
        if name.__class__.__name__ != 'Const':
            # Not a valid name, needs to be a const.
            return None
        if not isinstance(name.value, str):
            # Needs to be a string.
            return None

        # Verify the bases
        bases = next(caller.args[2].infer(context=context))
        if bases.__class__.__name__ != 'Tuple':
            # Needs to be a tuple.
            return None
        inferred_bases = [next(elt.infer(context=context))
                          for elt in bases.elts]
        if any(base.__class__.__name__ != 'ClassDef'
               for base in inferred_bases):
            # All the bases needs to be Classes
            return None

        # Verify the attributes.
        attrs = next(caller.args[3].infer(context=context))
        if attrs.__class__.__name__ != 'Dict':
            # Needs to be a dictionary.
            return None
        cls_locals = collections.defaultdict(list)
        for key, value in attrs.items:
            key = next(key.infer(context=context))
            value = next(value.infer(context=context))
            # Ignore non string keys
            if (key.__class__.__name__ == 'Const' and
                    isinstance(key.value, str)):
                cls_locals[key.value].append(value)

        # Build the class from now.
        cls = mcs.__class__(name=name.value, lineno=caller.lineno,
                            col_offset=caller.col_offset,
                            parent=caller)
        
        cls.postinit(
            bases=bases.elts, 
            body=nodes.Block('body', [node_classes.Pass()], cls), 
            decorators=[],
            newstyle=True, 
            metaclass=mcs, 
            keywords=[])
        cls.locals = cls_locals
        return cls