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
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
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
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
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
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
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
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
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
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
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
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
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
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