def _analysis(self): self._evaluator.is_analysis = True module_node = self._get_module_node() self._evaluator.analysis_modules = [module_node] try: for node in module_node.nodes_to_execute(): context = self._get_module().create_context(node) if node.type in ('funcdef', 'classdef'): # TODO This is stupid, should be private from jedi.evaluate.finder import _name_to_types # Resolve the decorators. _name_to_types(self._evaluator, context, node.children[1]) elif isinstance(node, tree.Import): import_names = set(node.get_defined_names()) if node.is_nested(): import_names |= set(path[-1] for path in node.paths()) for n in import_names: imports.infer_import(context, n) elif node.type == 'expr_stmt': types = context.eval_node(node) for testlist in node.children[:-1:2]: # Iterate tuples. unpack_tuple_to_dict(self._evaluator, types, testlist) else: try_iter_content(self._evaluator.goto_definitions(context, node)) self._evaluator.reset_recursion_limitations() ana = [a for a in self._evaluator.analysis if self.path == a.path] return sorted(set(ana), key=lambda x: x.line) finally: self._evaluator.is_analysis = False
def _analysis(self): self._evaluator.is_analysis = True module_node = self._get_module_node() self._evaluator.analysis_modules = [module_node] try: for node in get_executable_nodes(module_node): context = self._get_module().create_context(node) if node.type in ('funcdef', 'classdef'): # Resolve the decorators. tree_name_to_contexts(self._evaluator, context, node.children[1]) elif isinstance(node, tree.Import): import_names = set(node.get_defined_names()) if node.is_nested(): import_names |= set(path[-1] for path in node.get_paths()) for n in import_names: imports.infer_import(context, n) elif node.type == 'expr_stmt': types = context.eval_node(node) for testlist in node.children[:-1:2]: # Iterate tuples. unpack_tuple_to_dict(context, types, testlist) else: if node.type == 'name': defs = self._evaluator.goto_definitions(context, node) else: defs = evaluate_call_of_leaf(context, node) try_iter_content(defs) self._evaluator.reset_recursion_limitations() ana = [a for a in self._evaluator.analysis if self.path == a.path] return sorted(set(ana), key=lambda x: x.line) finally: self._evaluator.is_analysis = False
def goto_definitions(self, context, name): def_ = name.get_definition(import_name_always=True) if def_ is not None: type_ = def_.type is_classdef = type_ == 'classdef' if is_classdef or type_ == 'funcdef': if is_classdef: c = ClassContext(self, context, name.parent) else: c = FunctionContext.from_context(context, name.parent) return ContextSet([c]) if type_ == 'expr_stmt': is_simple_name = name.parent.type not in ('power', 'trailer') if is_simple_name: return eval_expr_stmt(context, def_, name) if type_ == 'for_stmt': container_types = context.eval_node(def_.children[3]) cn = ContextualizedNode(context, def_.children[3]) for_types = iterate_contexts(container_types, cn) c_node = ContextualizedName(context, name) return check_tuple_assignments(self, c_node, for_types) if type_ in ('import_from', 'import_name'): return imports.infer_import(context, name) else: result = self._follow_error_node_imports_if_possible(context, name) if result is not None: return result return helpers.evaluate_call_of_leaf(context, name)
def _name_to_types(evaluator, context, tree_name): types = [] node = tree_name.get_definition(import_name_always=True) if node is None: node = tree_name.parent if node.type == 'global_stmt': context = evaluator.create_context(context, tree_name) finder = NameFinder(evaluator, context, context, tree_name.value) filters = finder.get_filters(search_global=True) # For global_stmt lookups, we only need the first possible scope, # which means the function itself. filters = [next(filters)] return finder.find(filters, attribute_lookup=False) elif node.type not in ('import_from', 'import_name'): raise ValueError("Should not happen.") typ = node.type if typ == 'for_stmt': types = pep0484.find_type_from_comment_hint_for(context, node, tree_name) if types: return types if typ == 'with_stmt': types = pep0484.find_type_from_comment_hint_with(context, node, tree_name) if types: return types if typ in ('for_stmt', 'comp_for'): try: types = context.predefined_names[node][tree_name.value] except KeyError: cn = ContextualizedNode(context, node.children[3]) for_types = iterable.py__iter__types(evaluator, cn.infer(), cn) c_node = ContextualizedName(context, tree_name) types = check_tuple_assignments(evaluator, c_node, for_types) elif typ == 'expr_stmt': types = _remove_statements(evaluator, context, node, tree_name) elif typ == 'with_stmt': context_managers = context.eval_node(node.get_test_node_from_name(tree_name)) enter_methods = unite( context_manager.py__getattribute__('__enter__') for context_manager in context_managers ) types = unite(method.execute_evaluated() for method in enter_methods) elif typ in ('import_from', 'import_name'): types = imports.infer_import(context, tree_name) elif typ in ('funcdef', 'classdef'): types = _apply_decorators(evaluator, context, node) elif typ == 'try_stmt': # TODO an exception can also be a tuple. Check for those. # TODO check for types that are not classes and add it to # the static analysis report. exceptions = context.eval_node(tree_name.get_previous_sibling().get_previous_sibling()) types = unite( evaluator.execute(t, param.ValuesArguments([])) for t in exceptions ) else: raise ValueError("Should not happen.") return types
def tree_name_to_contexts(evaluator, context, tree_name): types = [] node = tree_name.get_definition(import_name_always=True) if node is None: node = tree_name.parent if node.type == 'global_stmt': context = evaluator.create_context(context, tree_name) finder = NameFinder(evaluator, context, context, tree_name.value) filters = finder.get_filters(search_global=True) # For global_stmt lookups, we only need the first possible scope, # which means the function itself. filters = [next(filters)] return finder.find(filters, attribute_lookup=False) elif node.type not in ('import_from', 'import_name'): raise ValueError("Should not happen.") typ = node.type if typ == 'for_stmt': types = pep0484.find_type_from_comment_hint_for( context, node, tree_name) if types: return types if typ == 'with_stmt': types = pep0484.find_type_from_comment_hint_with( context, node, tree_name) if types: return types if typ in ('for_stmt', 'comp_for'): try: types = context.predefined_names[node][tree_name.value] except KeyError: cn = ContextualizedNode(context, node.children[3]) for_types = iterate_contexts(cn.infer(), cn) c_node = ContextualizedName(context, tree_name) types = check_tuple_assignments(evaluator, c_node, for_types) elif typ == 'expr_stmt': types = _remove_statements(evaluator, context, node, tree_name) elif typ == 'with_stmt': context_managers = context.eval_node( node.get_test_node_from_name(tree_name)) enter_methods = context_managers.py__getattribute__('__enter__') return enter_methods.execute_evaluated() elif typ in ('import_from', 'import_name'): types = imports.infer_import(context, tree_name) elif typ in ('funcdef', 'classdef'): types = _apply_decorators(context, node) elif typ == 'try_stmt': # TODO an exception can also be a tuple. Check for those. id:627 gh:628 # TODO check for types that are not classes and add it to id:731 gh:732 # the static analysis report. exceptions = context.eval_node( tree_name.get_previous_sibling().get_previous_sibling()) types = exceptions.execute_evaluated() else: raise ValueError("Should not happen.") return types
def star_imports(self): modules = [] for i in self.tree_node.iter_imports(): if i.is_star_import(): name = i.get_paths()[-1][-1] new = imports.infer_import(self, name) for module in new: if isinstance(module, ModuleContext): modules += module.star_imports() modules += new return modules
def star_imports(self): modules = [] for i in self.tree_node.iter_imports(): if i.is_star_import(): name = i.get_paths()[-1][-1] new = infer_import(self, name) for module in new: if isinstance(module, ModuleContext): modules += module.star_imports() modules += new return modules
def star_imports(self): modules = [] for i in self.tree_node.imports: if i.is_star_import(): name = i.star_import_name() new = imports.infer_import(self, name) for module in new: if isinstance(module, ModuleContext): modules += module.star_imports() modules += new return modules
def resolve_potential_imports(evaluator, definitions): """ Adds the modules of the imports """ new = set() for d in definitions: if isinstance(d, TreeNameDefinition): imp_or_stmt = d.tree_name.get_definition() if isinstance(imp_or_stmt, tree.Import): new |= resolve_potential_imports( evaluator, set(imports.infer_import( d.parent_context, d.tree_name, is_goto=True )) ) return set(definitions) | new
def _name_to_types(evaluator, context, tree_name): types = [] node = tree_name.get_definition() if node.type == 'for_stmt': types = pep0484.find_type_from_comment_hint_for( context, node, tree_name) if types: return types if node.type == 'with_stmt': types = pep0484.find_type_from_comment_hint_with( context, node, tree_name) if types: return types if node.type in ('for_stmt', 'comp_for'): try: types = context.predefined_names[node][tree_name.value] except KeyError: container_types = context.eval_node(node.children[3]) for_types = iterable.py__iter__types(evaluator, container_types, node.children[3]) types = check_tuple_assignments(evaluator, for_types, tree_name) elif node.type == 'expr_stmt': types = _remove_statements(evaluator, context, node, tree_name) elif node.type == 'with_stmt': types = context.eval_node(node.node_from_name(tree_name)) elif isinstance(node, tree.Import): types = imports.infer_import(context, tree_name) elif node.type in ('funcdef', 'classdef'): types = _apply_decorators(evaluator, context, node) elif node.type == 'global_stmt': context = evaluator.create_context(context, tree_name) finder = NameFinder(evaluator, context, context, str(tree_name)) filters = finder.get_filters(search_global=True) # For global_stmt lookups, we only need the first possible scope, # which means the function itself. filters = [next(filters)] types += finder.find(filters, attribute_lookup=False) elif isinstance(node, tree.TryStmt): # TODO an exception can also be a tuple. Check for those. # TODO check for types that are not classes and add it to # the static analysis report. exceptions = context.eval_node( tree_name.get_previous_sibling().get_previous_sibling()) types = unite( evaluator.execute(t, param.ValuesArguments([])) for t in exceptions) else: raise ValueError("Should not happen.") return types
def _analysis(self): self._evaluator.is_analysis = True module_node = self._get_module_node() self._evaluator.analysis_modules = [module_node] try: for node in get_executable_nodes(module_node): context = self._get_module().create_context(node) if node.type in ('funcdef', 'classdef'): # TODO This is stupid, should be private from jedi.evaluate.finder import _name_to_types # Resolve the decorators. _name_to_types(self._evaluator, context, node.children[1]) elif isinstance(node, tree.Import): import_names = set(node.get_defined_names()) if node.is_nested(): import_names |= set(path[-1] for path in node.get_paths()) for n in import_names: imports.infer_import(context, n) elif node.type == 'expr_stmt': types = context.eval_node(node) for testlist in node.children[:-1:2]: # Iterate tuples. unpack_tuple_to_dict(context, types, testlist) else: if node.type == 'name': defs = self._evaluator.goto_definitions(context, node) else: defs = evaluate_call_of_leaf(context, node) try_iter_content(defs) self._evaluator.reset_recursion_limitations() ana = [a for a in self._evaluator.analysis if self.path == a.path] return sorted(set(ana), key=lambda x: x.line) finally: self._evaluator.is_analysis = False
def _name_to_types(evaluator, context, tree_name): types = [] node = tree_name.get_definition() if node.isinstance(tree.ForStmt): types = pep0484.find_type_from_comment_hint_for(context, node, tree_name) if types: return types if node.isinstance(tree.WithStmt): types = pep0484.find_type_from_comment_hint_with(context, node, tree_name) if types: return types if node.type in ('for_stmt', 'comp_for'): try: types = context.predefined_names[node][tree_name.value] except KeyError: container_types = context.eval_node(node.children[3]) for_types = iterable.py__iter__types(evaluator, container_types, node.children[3]) types = check_tuple_assignments(evaluator, for_types, tree_name) elif node.isinstance(tree.ExprStmt): types = _remove_statements(evaluator, context, node, tree_name) elif node.isinstance(tree.WithStmt): types = context.eval_node(node.node_from_name(tree_name)) elif isinstance(node, tree.Import): types = imports.infer_import(context, tree_name) elif node.type in ('funcdef', 'classdef'): types = _apply_decorators(evaluator, context, node) elif node.type == 'global_stmt': context = evaluator.create_context(context, tree_name) finder = NameFinder(evaluator, context, context, str(tree_name)) filters = finder.get_filters(search_global=True) # For global_stmt lookups, we only need the first possible scope, # which means the function itself. filters = [next(filters)] types += finder.find(filters, attribute_lookup=False) elif isinstance(node, tree.TryStmt): # TODO an exception can also be a tuple. Check for those. # TODO check for types that are not classes and add it to # the static analysis report. exceptions = context.eval_node(tree_name.get_previous_sibling().get_previous_sibling()) types = unite( evaluator.execute(t, param.ValuesArguments([])) for t in exceptions ) else: raise ValueError("Should not happen.") return types
def goto_definitions(self, context, name): def_ = name.get_definition() is_simple_name = name.parent.type not in ('power', 'trailer') if is_simple_name: if name.parent.type == 'classdef' and name.parent.name == name: return [er.ClassContext(self, name.parent, context)] elif name.parent.type == 'funcdef': return [er.FunctionContext(self, context, name.parent)] elif name.parent.type == 'file_input': raise NotImplementedError if def_.type == 'expr_stmt' and name in def_.get_defined_names(): return self.eval_statement(context, def_, name) elif def_.type == 'for_stmt': container_types = self.eval_element(context, def_.children[3]) for_types = iterable.py__iter__types(self, container_types, def_.children[3]) return finder.check_tuple_assignments(self, for_types, name) elif def_.type in ('import_from', 'import_name'): return imports.infer_import(context, name) return helpers.evaluate_call_of_leaf(context, name)
def goto_definitions(self, context, name): def_ = name.get_definition() is_simple_name = name.parent.type not in ('power', 'trailer') if is_simple_name: if name.parent.type == 'classdef' and name.parent.name == name: return [er.ClassContext(self, name.parent, context)] elif name.parent.type == 'funcdef': return [er.FunctionContext(self, context, name.parent)] elif name.parent.type == 'file_input': raise NotImplementedError if def_.type == 'expr_stmt' and name in def_.get_defined_names(): return self.eval_statement(context, def_, name) elif def_.type == 'for_stmt': container_types = self.eval_element(context, def_.children[3]) cn = ContextualizedNode(context, def_.children[3]) for_types = iterable.py__iter__types(self, container_types, cn) c_node = ContextualizedName(context, name) return finder.check_tuple_assignments(self, c_node, for_types) elif def_.type in ('import_from', 'import_name'): return imports.infer_import(context, name) return helpers.evaluate_call_of_leaf(context, name)
def goto_definitions(self, context, name): def_ = name.get_definition(import_name_always=True) if def_ is not None: type_ = def_.type if type_ == 'classdef': return [ClassContext(self, context, name.parent)] elif type_ == 'funcdef': return [FunctionContext(self, context, name.parent)] if type_ == 'expr_stmt': is_simple_name = name.parent.type not in ('power', 'trailer') if is_simple_name: return eval_expr_stmt(context, def_, name) if type_ == 'for_stmt': container_types = context.eval_node(def_.children[3]) cn = ContextualizedNode(context, def_.children[3]) for_types = iterate_contexts(container_types, cn) c_node = ContextualizedName(context, name) return check_tuple_assignments(self, c_node, for_types) if type_ in ('import_from', 'import_name'): return imports.infer_import(context, name) return helpers.evaluate_call_of_leaf(context, name)
def _goto(self, context, name): definition = name.get_definition(import_name_always=True) if definition is not None: type_ = definition.type if type_ == 'expr_stmt': # Only take the parent, because if it's more complicated than just # a name it's something you can "goto" again. is_simple_name = name.parent.type not in ('power', 'trailer') if is_simple_name: return [TreeNameDefinition(context, name)] elif type_ == 'param': return [ParamName(context, name)] elif type_ in ('funcdef', 'classdef'): return [TreeNameDefinition(context, name)] elif type_ in ('import_from', 'import_name'): module_names = imports.infer_import(context, name, is_goto=True) return module_names else: contexts = self._follow_error_node_imports_if_possible(context, name) if contexts is not None: return [context.name for context in contexts] par = name.parent node_type = par.type if node_type == 'argument' and par.children[1] == '=' and par.children[0] == name: # Named param goto. trailer = par.parent if trailer.type == 'arglist': trailer = trailer.parent if trailer.type != 'classdef': if trailer.type == 'decorator': context_set = context.eval_node(trailer.children[1]) else: i = trailer.parent.children.index(trailer) to_evaluate = trailer.parent.children[:i] if to_evaluate[0] == 'await': to_evaluate.pop(0) context_set = context.eval_node(to_evaluate[0]) for trailer in to_evaluate[1:]: context_set = eval_trailer(context, context_set, trailer) param_names = [] for context in context_set: for signature in context.get_signatures(): for param_name in signature.get_param_names(): if param_name.string_name == name.value: param_names.append(param_name) return param_names elif node_type == 'dotted_name': # Is a decorator. index = par.children.index(name) if index > 0: new_dotted = helpers.deep_ast_copy(par) new_dotted.children[index - 1:] = [] values = context.eval_node(new_dotted) return unite( value.py__getattribute__(name, name_context=context, is_goto=True) for value in values ) if node_type == 'trailer' and par.children[0] == '.': values = helpers.evaluate_call_of_leaf(context, name, cut_own_trailer=True) return unite( value.py__getattribute__(name, name_context=context, is_goto=True) for value in values ) else: stmt = tree.search_ancestor( name, 'expr_stmt', 'lambdef' ) or name if stmt.type == 'lambdef': stmt = name return context.py__getattribute__( name, position=stmt.start_pos, search_global=True, is_goto=True )
def goto(self, context, name): stmt = name.get_definition() par = name.parent if par.type == 'argument' and par.children[1] == '=' and par.children[ 0] == name: # Named param goto. trailer = par.parent if trailer.type == 'arglist': trailer = trailer.parent if trailer.type != 'classdef': if trailer.type == 'decorator': types = self.eval_element(context, trailer.children[1]) else: i = trailer.parent.children.index(trailer) to_evaluate = trailer.parent.children[:i] types = self.eval_element(context, to_evaluate[0]) for trailer in to_evaluate[1:]: types = self.eval_trailer(context, types, trailer) param_names = [] for typ in types: try: get_param_names = typ.get_param_names except AttributeError: pass else: for param_name in get_param_names(): if param_name.string_name == name.value: param_names.append(param_name) return param_names elif par.type == 'expr_stmt' and name in par.get_defined_names(): # Only take the parent, because if it's more complicated than just # a name it's something you can "goto" again. return [TreeNameDefinition(context, name)] elif par.type == 'param' and par.name: return [ParamName(context, name)] elif isinstance( par, (tree.Param, tree.Function, tree.Class)) and par.name is name: return [TreeNameDefinition(context, name)] elif isinstance(stmt, tree.Import): module_names = imports.infer_import(context, name, is_goto=True) return module_names elif par.type == 'dotted_name': # Is a decorator. index = par.children.index(name) if index > 0: new_dotted = helpers.deep_ast_copy(par) new_dotted.children[index - 1:] = [] values = self.eval_element(context, new_dotted) return unite( value.py__getattribute__( name, name_context=context, is_goto=True) for value in values) if par.type == 'trailer' and par.children[0] == '.': values = helpers.evaluate_call_of_leaf(context, name, cut_own_trailer=True) return unite( value.py__getattribute__( name, name_context=context, is_goto=True) for value in values) else: if stmt.type != 'expr_stmt': # We only need to adjust the start_pos for statements, because # there the name cannot be used. stmt = name return context.py__getattribute__(name, position=stmt.start_pos, search_global=True, is_goto=True)
def goto(self, context, name): definition = name.get_definition(import_name_always=True) if definition is not None: type_ = definition.type if type_ == 'expr_stmt': # Only take the parent, because if it's more complicated than just # a name it's something you can "goto" again. is_simple_name = name.parent.type not in ('power', 'trailer') if is_simple_name: return [TreeNameDefinition(context, name)] elif type_ == 'param': return [ParamName(context, name)] elif type_ in ('funcdef', 'classdef'): return [TreeNameDefinition(context, name)] elif type_ in ('import_from', 'import_name'): module_names = imports.infer_import(context, name, is_goto=True) return module_names par = name.parent node_type = par.type if node_type == 'argument' and par.children[1] == '=' and par.children[0] == name: # Named param goto. trailer = par.parent if trailer.type == 'arglist': trailer = trailer.parent if trailer.type != 'classdef': if trailer.type == 'decorator': context_set = context.eval_node(trailer.children[1]) else: i = trailer.parent.children.index(trailer) to_evaluate = trailer.parent.children[:i] if to_evaluate[0] == 'await': to_evaluate.pop(0) context_set = context.eval_node(to_evaluate[0]) for trailer in to_evaluate[1:]: context_set = eval_trailer(context, context_set, trailer) param_names = [] for context in context_set: try: get_param_names = context.get_param_names except AttributeError: pass else: for param_name in get_param_names(): if param_name.string_name == name.value: param_names.append(param_name) return param_names elif node_type == 'dotted_name': # Is a decorator. index = par.children.index(name) if index > 0: new_dotted = helpers.deep_ast_copy(par) new_dotted.children[index - 1:] = [] values = context.eval_node(new_dotted) return unite( value.py__getattribute__(name, name_context=context, is_goto=True) for value in values ) if node_type == 'trailer' and par.children[0] == '.': values = helpers.evaluate_call_of_leaf(context, name, cut_own_trailer=True) return unite( value.py__getattribute__(name, name_context=context, is_goto=True) for value in values ) else: stmt = tree.search_ancestor( name, 'expr_stmt', 'lambdef' ) or name if stmt.type == 'lambdef': stmt = name return context.py__getattribute__( name, position=stmt.start_pos, search_global=True, is_goto=True )
def tree_name_to_contexts(evaluator, context, tree_name): context_set = ContextSet() module_node = context.get_root_context().tree_node if module_node is not None: names = module_node.get_used_names().get(tree_name.value, []) for name in names: expr_stmt = name.parent correct_scope = parser_utils.get_parent_scope(name) == context.tree_node if expr_stmt.type == "expr_stmt" and expr_stmt.children[1].type == "annassign" and correct_scope: context_set |= _evaluate_for_annotation(context, expr_stmt.children[1].children[1]) if context_set: return context_set types = [] node = tree_name.get_definition(import_name_always=True) if node is None: node = tree_name.parent if node.type == 'global_stmt': context = evaluator.create_context(context, tree_name) finder = NameFinder(evaluator, context, context, tree_name.value) filters = finder.get_filters(search_global=True) # For global_stmt lookups, we only need the first possible scope, # which means the function itself. filters = [next(filters)] return finder.find(filters, attribute_lookup=False) elif node.type not in ('import_from', 'import_name'): raise ValueError("Should not happen. type: %s", node.type) typ = node.type if typ == 'for_stmt': types = pep0484.find_type_from_comment_hint_for(context, node, tree_name) if types: return types if typ == 'with_stmt': types = pep0484.find_type_from_comment_hint_with(context, node, tree_name) if types: return types if typ in ('for_stmt', 'comp_for'): try: types = context.predefined_names[node][tree_name.value] except KeyError: cn = ContextualizedNode(context, node.children[3]) for_types = iterate_contexts( cn.infer(), contextualized_node=cn, is_async=node.parent.type == 'async_stmt', ) c_node = ContextualizedName(context, tree_name) types = check_tuple_assignments(evaluator, c_node, for_types) elif typ == 'expr_stmt': types = _remove_statements(evaluator, context, node, tree_name) elif typ == 'with_stmt': context_managers = context.eval_node(node.get_test_node_from_name(tree_name)) enter_methods = context_managers.py__getattribute__(u'__enter__') return enter_methods.execute_evaluated() elif typ in ('import_from', 'import_name'): types = imports.infer_import(context, tree_name) elif typ in ('funcdef', 'classdef'): types = _apply_decorators(context, node) elif typ == 'try_stmt': # TODO an exception can also be a tuple. Check for those. # TODO check for types that are not classes and add it to # the static analysis report. exceptions = context.eval_node(tree_name.get_previous_sibling().get_previous_sibling()) types = exceptions.execute_evaluated() else: raise ValueError("Should not happen. type: %s" % typ) return types
def goto(self, context, name): stmt = name.get_definition() par = name.parent if par.type == 'argument' and par.children[1] == '=' and par.children[0] == name: # Named param goto. trailer = par.parent if trailer.type == 'arglist': trailer = trailer.parent if trailer.type != 'classdef': if trailer.type == 'decorator': types = self.eval_element(context, trailer.children[1]) else: i = trailer.parent.children.index(trailer) to_evaluate = trailer.parent.children[:i] types = self.eval_element(context, to_evaluate[0]) for trailer in to_evaluate[1:]: types = self.eval_trailer(context, types, trailer) param_names = [] for typ in types: try: get_param_names = typ.get_param_names except AttributeError: pass else: for param_name in get_param_names(): if param_name.string_name == name.value: param_names.append(param_name) return param_names elif par.type == 'expr_stmt' and name in par.get_defined_names(): # Only take the parent, because if it's more complicated than just # a name it's something you can "goto" again. return [TreeNameDefinition(context, name)] elif par.type == 'param' and par.name: return [ParamName(context, name)] elif isinstance(par, (tree.Param, tree.Function, tree.Class)) and par.name is name: return [TreeNameDefinition(context, name)] elif isinstance(stmt, tree.Import): module_names = imports.infer_import(context, name, is_goto=True) return module_names elif par.type == 'dotted_name': # Is a decorator. index = par.children.index(name) if index > 0: new_dotted = helpers.deep_ast_copy(par) new_dotted.children[index - 1:] = [] values = self.eval_element(context, new_dotted) return unite( value.py__getattribute__(name, name_context=context, is_goto=True) for value in values ) if par.type == 'trailer' and par.children[0] == '.': values = helpers.evaluate_call_of_leaf(context, name, cut_own_trailer=True) return unite( value.py__getattribute__(name, name_context=context, is_goto=True) for value in values ) else: if stmt.type != 'expr_stmt': # We only need to adjust the start_pos for statements, because # there the name cannot be used. stmt = name return context.py__getattribute__( name, position=stmt.start_pos, search_global=True, is_goto=True )
def tree_name_to_contexts(evaluator, context, tree_name): context_set = NO_CONTEXTS module_node = context.get_root_context().tree_node # First check for annotations, like: `foo: int = 3` if module_node is not None: names = module_node.get_used_names().get(tree_name.value, []) for name in names: expr_stmt = name.parent if expr_stmt.type == "expr_stmt" and expr_stmt.children[ 1].type == "annassign": correct_scope = parser_utils.get_parent_scope( name) == context.tree_node if correct_scope: context_set |= annotation.eval_annotation( context, expr_stmt.children[1].children[1]).execute_annotation( ) if context_set: return context_set types = [] node = tree_name.get_definition(import_name_always=True) if node is None: node = tree_name.parent if node.type == 'global_stmt': context = evaluator.create_context(context, tree_name) finder = NameFinder(evaluator, context, context, tree_name.value) filters = finder.get_filters(search_global=True) # For global_stmt lookups, we only need the first possible scope, # which means the function itself. filters = [next(filters)] return finder.find(filters, attribute_lookup=False) elif node.type not in ('import_from', 'import_name'): context = evaluator.create_context(context, tree_name) return eval_atom(context, tree_name) typ = node.type if typ == 'for_stmt': types = annotation.find_type_from_comment_hint_for( context, node, tree_name) if types: return types if typ == 'with_stmt': types = annotation.find_type_from_comment_hint_with( context, node, tree_name) if types: return types if typ in ('for_stmt', 'comp_for', 'sync_comp_for'): try: types = context.predefined_names[node][tree_name.value] except KeyError: cn = ContextualizedNode(context, node.children[3]) for_types = iterate_contexts( cn.infer(), contextualized_node=cn, is_async=node.parent.type == 'async_stmt', ) c_node = ContextualizedName(context, tree_name) types = check_tuple_assignments(evaluator, c_node, for_types) elif typ == 'expr_stmt': types = _remove_statements(evaluator, context, node, tree_name) elif typ == 'with_stmt': context_managers = context.eval_node( node.get_test_node_from_name(tree_name)) enter_methods = context_managers.py__getattribute__(u'__enter__') return enter_methods.execute_evaluated() elif typ in ('import_from', 'import_name'): types = imports.infer_import(context, tree_name) elif typ in ('funcdef', 'classdef'): types = _apply_decorators(context, node) elif typ == 'try_stmt': # TODO an exception can also be a tuple. Check for those. # TODO check for types that are not classes and add it to # the static analysis report. exceptions = context.eval_node( tree_name.get_previous_sibling().get_previous_sibling()) types = exceptions.execute_evaluated() elif node.type == 'param': types = NO_CONTEXTS else: raise ValueError("Should not happen. type: %s" % typ) return types