Exemplo n.º 1
0
        def from_scope_node(scope_node, child_is_funcdef=None, is_nested=True, node_is_object=False):
            if scope_node == base_node:
                return base_context

            is_funcdef = scope_node.type in ('funcdef', 'lambdef')
            parent_scope = parser_utils.get_parent_scope(scope_node)
            parent_context = from_scope_node(parent_scope, child_is_funcdef=is_funcdef)

            if is_funcdef:
                if isinstance(parent_context, AnonymousInstance):
                    func = BoundMethod(
                        self, parent_context, parent_context.class_context,
                        parent_context.parent_context, scope_node
                    )
                else:
                    func = FunctionContext(
                        self,
                        parent_context,
                        scope_node
                    )
                if is_nested and not node_is_object:
                    return func.get_function_execution()
                return func
            elif scope_node.type == 'classdef':
                class_context = ClassContext(self, parent_context, scope_node)
                if child_is_funcdef:
                    # anonymous instance
                    return AnonymousInstance(self, parent_context, class_context)
                else:
                    return class_context
            elif scope_node.type == 'comp_for':
                if node.start_pos >= scope_node.children[-1].start_pos:
                    return parent_context
                return CompForContext.from_comp_for(parent_context, scope_node)
            raise Exception("There's a scope that was not managed.")
Exemplo n.º 2
0
 def create_instance_context(self, class_context, node):
     if node.parent.type in ('funcdef', 'classdef'):
         node = node.parent
     scope = get_parent_scope(node)
     if scope == class_context.tree_node:
         return class_context
     else:
         parent_context = self.create_instance_context(class_context, scope)
         if scope.type == 'funcdef':
             func = FunctionContext.from_context(
                 parent_context,
                 scope,
             )
             bound_method = BoundMethod(self, func)
             if scope.name.value == '__init__' and parent_context == class_context:
                 return bound_method.get_function_execution(self.var_args)
             else:
                 return bound_method.get_function_execution()
         elif scope.type == 'classdef':
             class_context = ClassContext(self.evaluator, parent_context, scope)
             return class_context
         elif scope.type == 'comp_for':
             # Comprehensions currently don't have a special scope in Jedi.
             return self.create_instance_context(class_context, scope)
         else:
             raise NotImplementedError
     return class_context
Exemplo n.º 3
0
        def from_scope_node(scope_node, child_is_funcdef=None, is_nested=True, node_is_object=False):
            if scope_node == base_node:
                return base_context

            is_funcdef = scope_node.type in ('funcdef', 'lambdef')
            parent_scope = parser_utils.get_parent_scope(scope_node)
            parent_context = from_scope_node(parent_scope, child_is_funcdef=is_funcdef)

            if is_funcdef:
                if isinstance(parent_context, AnonymousInstance):
                    func = BoundMethod(
                        self, parent_context, parent_context.class_context,
                        parent_context.parent_context, scope_node
                    )
                else:
                    func = er.FunctionContext(
                        self,
                        parent_context,
                        scope_node
                    )
                if is_nested and not node_is_object:
                    return func.get_function_execution()
                return func
            elif scope_node.type == 'classdef':
                class_context = er.ClassContext(self, scope_node, parent_context)
                if child_is_funcdef:
                    # anonymous instance
                    return AnonymousInstance(self, parent_context, class_context)
                else:
                    return class_context
            elif scope_node.type == 'comp_for':
                if node.start_pos >= scope_node.children[-1].start_pos:
                    return parent_context
                return iterable.CompForContext.from_comp_for(parent_context, scope_node)
            raise Exception("There's a scope that was not managed.")
Exemplo n.º 4
0
    def _names_to_types(self, names, attribute_lookup):
        types = set()

        types = unite(name.infer() for name in names)

        debug.dbg('finder._names_to_types: %s -> %s', names, types)
        if not names and isinstance(self._context, AbstractInstanceContext):
            # handling __getattr__ / __getattribute__
            return self._check_getattr(self._context)

        # Add isinstance and other if/assert knowledge.
        if not types and isinstance(self._name, tree.Name) and \
                not isinstance(self._name_context, AbstractInstanceContext):
            flow_scope = self._name
            base_node = self._name_context.tree_node
            if base_node.type == 'comp_for':
                return types
            while True:
                flow_scope = get_parent_scope(flow_scope, include_flows=True)
                n = _check_flow_information(self._name_context, flow_scope,
                                            self._name, self._position)
                if n is not None:
                    return n
                if flow_scope == base_node:
                    break
        return types
Exemplo n.º 5
0
 def _equals_origin_scope(self):
     node = self._origin_scope
     while node is not None:
         if node == self._parser_scope or node == self.context:
             return True
         node = get_parent_scope(node)
     return False
Exemplo n.º 6
0
def _break_check(context, value_scope, flow_scope, node):
    reachable = REACHABLE
    if flow_scope.type == 'if_stmt':
        if flow_scope.is_node_after_else(node):
            for check_node in flow_scope.get_test_nodes():
                reachable = _check_if(context, check_node)
                if reachable in (REACHABLE, UNSURE):
                    break
            reachable = reachable.invert()
        else:
            flow_node = flow_scope.get_corresponding_test_node(node)
            if flow_node is not None:
                reachable = _check_if(context, flow_node)
    elif flow_scope.type in ('try_stmt', 'while_stmt'):
        return UNSURE

    # Only reachable branches need to be examined further.
    if reachable in (UNREACHABLE, UNSURE):
        return reachable

    if value_scope != flow_scope and value_scope != flow_scope.parent:
        flow_scope = get_parent_scope(flow_scope, include_flows=True)
        return reachable & _break_check(context, value_scope, flow_scope, node)
    else:
        return reachable
Exemplo n.º 7
0
    def _names_to_types(self, names, attribute_lookup):
        contexts = ContextSet.from_sets(name.infer() for name in names)

        debug.dbg('finder._names_to_types: %s -> %s', names, contexts)
        if not names and self._context.is_instance(
        ) and not self._context.is_compiled():
            # handling __getattr__ / __getattribute__
            return self._check_getattr(self._context)

        # Add isinstance and other if/assert knowledge.
        if not contexts and isinstance(self._name, tree.Name) and \
                not self._name_context.is_instance() and not self._context.is_compiled():
            flow_scope = self._name
            base_nodes = [self._name_context.tree_node]

            if any(b.type in ('comp_for', 'sync_comp_for')
                   for b in base_nodes):
                return contexts
            while True:
                flow_scope = get_parent_scope(flow_scope, include_flows=True)
                n = _check_flow_information(self._name_context, flow_scope,
                                            self._name, self._position)
                if n is not None:
                    return n
                if flow_scope in base_nodes:
                    break
        return contexts
Exemplo n.º 8
0
def _break_check(context, context_scope, flow_scope, node):
    reachable = REACHABLE
    if flow_scope.type == 'if_stmt':
        if flow_scope.is_node_after_else(node):
            for check_node in flow_scope.get_test_nodes():
                reachable = _check_if(context, check_node)
                if reachable in (REACHABLE, UNSURE):
                    break
            reachable = reachable.invert()
        else:
            flow_node = flow_scope.get_corresponding_test_node(node)
            if flow_node is not None:
                reachable = _check_if(context, flow_node)
    elif flow_scope.type in ('try_stmt', 'while_stmt'):
        return UNSURE

    # Only reachable branches need to be examined further.
    if reachable in (UNREACHABLE, UNSURE):
        return reachable

    if context_scope != flow_scope and context_scope != flow_scope.parent:
        flow_scope = get_parent_scope(flow_scope, include_flows=True)
        return reachable & _break_check(context, context_scope, flow_scope, node)
    else:
        return reachable
Exemplo n.º 9
0
def reachability_check(context, context_scope, node, origin_scope=None):
    first_flow_scope = get_parent_scope(node, include_flows=True)
    if origin_scope is not None:
        origin_flow_scopes = list(_get_flow_scopes(origin_scope))
        node_flow_scopes = list(_get_flow_scopes(node))

        branch_matches = True
        for flow_scope in origin_flow_scopes:
            if flow_scope in node_flow_scopes:
                node_keyword = get_flow_branch_keyword(flow_scope, node)
                origin_keyword = get_flow_branch_keyword(
                    flow_scope, origin_scope)
                branch_matches = node_keyword == origin_keyword
                if flow_scope.type == 'if_stmt':
                    if not branch_matches:
                        return UNREACHABLE
                elif flow_scope.type == 'try_stmt':
                    if not branch_matches and origin_keyword == 'else' \
                            and node_keyword == 'except':
                        return UNREACHABLE
                break

        # Direct parents get resolved, we filter scopes that are separate
        # branches.  This makes sense for autocompletion and static analysis.
        # For actual Python it doesn't matter, because we're talking about
        # potentially unreachable code.
        # e.g. `if 0:` would cause all name lookup within the flow make
        # unaccessible. This is not a "problem" in Python, because the code is
        # never called. In Jedi though, we still want to infer types.
        while origin_scope is not None:
            if first_flow_scope == origin_scope and branch_matches:
                return REACHABLE
            origin_scope = origin_scope.parent

    return _break_check(context, context_scope, first_flow_scope, node)
Exemplo n.º 10
0
def reachability_check(context, context_scope, node, origin_scope=None):
    first_flow_scope = get_parent_scope(node, include_flows=True)
    if origin_scope is not None:
        origin_flow_scopes = list(_get_flow_scopes(origin_scope))
        node_flow_scopes = list(_get_flow_scopes(node))

        branch_matches = True
        for flow_scope in origin_flow_scopes:
            if flow_scope in node_flow_scopes:
                node_keyword = get_flow_branch_keyword(flow_scope, node)
                origin_keyword = get_flow_branch_keyword(flow_scope, origin_scope)
                branch_matches = node_keyword == origin_keyword
                if flow_scope.type == 'if_stmt':
                    if not branch_matches:
                        return UNREACHABLE
                elif flow_scope.type == 'try_stmt':
                    if not branch_matches and origin_keyword == 'else' \
                            and node_keyword == 'except':
                        return UNREACHABLE
                if branch_matches:
                    break

        # Direct parents get resolved, we filter scopes that are separate
        # branches.  This makes sense for autocompletion and static analysis.
        # For actual Python it doesn't matter, because we're talking about
        # potentially unreachable code.
        # e.g. `if 0:` would cause all name lookup within the flow make
        # unaccessible. This is not a "problem" in Python, because the code is
        # never called. In Jedi though, we still want to infer types.
        while origin_scope is not None:
            if first_flow_scope == origin_scope and branch_matches:
                return REACHABLE
            origin_scope = origin_scope.parent

    return _break_check(context, context_scope, first_flow_scope, node)
Exemplo n.º 11
0
        def from_scope_node(scope_node, is_nested=True, node_is_object=False):
            if scope_node == base_node:
                return base_context

            is_funcdef = scope_node.type in ('funcdef', 'lambdef')
            parent_scope = parser_utils.get_parent_scope(scope_node)
            parent_context = from_scope_node(parent_scope)

            if is_funcdef:
                func = FunctionContext.from_context(parent_context, scope_node)
                if parent_context.is_class():
                    instance = AnonymousInstance(
                        self, parent_context.parent_context, parent_context)
                    func = BoundMethod(
                        instance=instance,
                        function=func
                    )

                if is_nested and not node_is_object:
                    return func.get_function_execution()
                return func
            elif scope_node.type == 'classdef':
                return ClassContext(self, parent_context, scope_node)
            elif scope_node.type == 'comp_for':
                if node.start_pos >= scope_node.children[-1].start_pos:
                    return parent_context
                return CompForContext.from_comp_for(parent_context, scope_node)
            raise Exception("There's a scope that was not managed.")
Exemplo n.º 12
0
 def create_instance_context(self, class_context, node):
     if node.parent.type in ('funcdef', 'classdef'):
         node = node.parent
     scope = get_parent_scope(node)
     if scope == class_context.tree_node:
         return class_context
     else:
         parent_context = self.create_instance_context(class_context, scope)
         if scope.type == 'funcdef':
             if scope.name.value == '__init__' and parent_context == class_context:
                 return self._create_init_execution(class_context, scope)
             else:
                 bound_method = BoundMethod(
                     self.evaluator, self, class_context,
                     parent_context, scope
                 )
                 return bound_method.get_function_execution()
         elif scope.type == 'classdef':
             class_context = ClassContext(self.evaluator, scope, parent_context)
             return class_context
         elif scope.type == 'comp_for':
             # Comprehensions currently don't have a special scope in Jedi.
             return self.create_instance_context(class_context, scope)
         else:
             raise NotImplementedError
     return class_context
Exemplo n.º 13
0
    def _names_to_types(self, names, attribute_lookup):
        types = set()

        types = unite(name.infer() for name in names)

        debug.dbg('finder._names_to_types: %s -> %s', names, types)
        if not names and isinstance(self._context, AbstractInstanceContext):
            # handling __getattr__ / __getattribute__
            return self._check_getattr(self._context)

        # Add isinstance and other if/assert knowledge.
        if not types and isinstance(self._name, tree.Name) and \
                not isinstance(self._name_context, AbstractInstanceContext):
            flow_scope = self._name
            base_node = self._name_context.tree_node
            if base_node.type == 'comp_for':
                return types
            while True:
                flow_scope = get_parent_scope(flow_scope, include_flows=True)
                n = _check_flow_information(self._name_context, flow_scope,
                                            self._name, self._position)
                if n is not None:
                    return n
                if flow_scope == base_node:
                    break
        return types
Exemplo n.º 14
0
 def _equals_origin_scope(self):
     node = self._origin_scope
     while node is not None:
         if node == self._parser_scope or node == self.context:
             return True
         node = get_parent_scope(node)
     return False
Exemplo n.º 15
0
 def py__class__(self):
     # This differentiation is only necessary for Python2. Python3 does not
     # use a different method class.
     if isinstance(parser_utils.get_parent_scope(self.tree_node), tree.Class):
         name = 'METHOD_CLASS'
     else:
         name = 'FUNCTION_CLASS'
     return compiled.get_special_object(self.evaluator, name)
Exemplo n.º 16
0
def get_parent_scope(node):
    try:
        # jedi 0.11
        from jedi import parser_utils
        return parser_utils.get_parent_scope(node)
    except ImportError:
        # Older versions
        return node.get_parent_scope()
Exemplo n.º 17
0
 def py__class__(self):
     # This differentiation is only necessary for Python2. Python3 does not
     # use a different method class.
     if isinstance(parser_utils.get_parent_scope(self.tree_node), tree.Class):
         name = u'METHOD_CLASS'
     else:
         name = u'FUNCTION_CLASS'
     return compiled.get_special_object(self.evaluator, name)
Exemplo n.º 18
0
 def _is_name_reachable(self, name):
     if not name.is_definition():
         return False
     parent = name.parent
     if parent.type == 'trailer':
         return False
     base_node = parent if parent.type in ('classdef', 'funcdef') else name
     return get_parent_scope(base_node) == self._parser_scope
Exemplo n.º 19
0
    def _find_definition(self, scope, name):
        from jedi import parser_utils

        # if the name is the name of a function definition
        if isinstance(scope, tree.Function):
            if scope.children[1] == name:
                return scope.children[1]  # 0th child is keyword "def", 1st is name
            else:
                definition = self._get_def_from_function_params(scope, name)
                if definition:
                    return definition

        for c in scope.children:
            if (
                isinstance(c, tree.BaseNode)
                and c.type == "simple_stmt"
                and isinstance(c.children[0], tree.ImportName)
            ):
                for n in c.children[0].get_defined_names():
                    if n.value == name.value:
                        return n
                # print(c.path_for_name(name.value))
            if (
                isinstance(c, tree.Function)
                and c.children[1].value == name.value
                and not isinstance(parser_utils.get_parent_scope(c), tree.Class)
            ):
                return c.children[1]
            if isinstance(c, tree.BaseNode) and c.type == "suite":
                for x in c.children:
                    if self._is_global_stmt_with_name(x, name.value):
                        return self._find_definition(parser_utils.get_parent_scope(scope), name)
                    if isinstance(x, tree.Name) and x.is_definition() and x.value == name.value:
                        return x
                    def_candidate = self._find_def_in_simple_node(x, name)
                    if def_candidate:
                        return def_candidate

        if not isinstance(scope, tree.Module):
            return self._find_definition(parser_utils.get_parent_scope(scope), name)

        # if name itself is the left side of an assignment statement, then the name is the definition
        if name.is_definition():
            return name

        return None
Exemplo n.º 20
0
 def _is_name_reachable(self, name):
     if not name.is_definition():
         return False
     parent = name.parent
     if parent.type == 'trailer':
         return False
     base_node = parent if parent.type in ('classdef', 'funcdef') else name
     return get_parent_scope(base_node) == self._parser_scope
Exemplo n.º 21
0
        def find_usages_in_node(node, global_encountered=False):
            names = []
            if isinstance(node, tree.BaseNode):
                if parser_utils.is_scope(node):
                    global_encountered = False
                    if node in searched_scopes:
                        return names
                    searched_scopes.add(node)
                    if isinstance(node, tree.Function):
                        d = self._get_def_from_function_params(node, name)
                        if d and d != definition:
                            return []

                for c in node.children:
                    dot_names = self._get_dot_names(c)
                    if len(dot_names) > 1 and dot_names[1].value == name.value:
                        continue
                    sub_result = find_usages_in_node(c, global_encountered=global_encountered)

                    if sub_result is None:
                        if not parser_utils.is_scope(node):
                            return (
                                None
                                if definition and node != parser_utils.get_parent_scope(definition)
                                else [definition]
                            )
                        else:
                            sub_result = []
                    names.extend(sub_result)
                    if self._is_global_stmt_with_name(c, name.value):
                        global_encountered = True
            elif isinstance(node, tree.Name) and node.value == name.value:
                if definition and definition != node:
                    if self._is_name_function_definition(node):
                        if isinstance(
                            parser_utils.get_parent_scope(parser_utils.get_parent_scope(node)),
                            tree.Class,
                        ):
                            return []
                        else:
                            return None
                    if (
                        node.is_definition()
                        and not global_encountered
                        and (
                            is_function_definition
                            or parser_utils.get_parent_scope(node)
                            != parser_utils.get_parent_scope(definition)
                        )
                    ):
                        return None
                    if self._is_name_function_definition(definition) and isinstance(
                        parser_utils.get_parent_scope(parser_utils.get_parent_scope(definition)),
                        tree.Class,
                    ):
                        return None
                names.append(node)
            return names
Exemplo n.º 22
0
def get_module_names(module, all_scopes):
    """
    Returns a dictionary with name parts as keys and their call paths as
    values.
    """
    names = chain.from_iterable(module.get_used_names().values())
    if not all_scopes:
        # We have to filter all the names that don't have the module as a
        # parent_scope. There's None as a parent, because nodes in the module
        # node have the parent module and not suite as all the others.
        # Therefore it's important to catch that case.
        names = [n for n in names if get_parent_scope(n).parent in (module, None)]
    return names
Exemplo n.º 23
0
def get_module_names(module, all_scopes):
    """
    Returns a dictionary with name parts as keys and their call paths as
    values.
    """
    names = chain.from_iterable(module.get_used_names().values())
    if not all_scopes:
        # We have to filter all the names that don't have the module as a
        # parent_scope. There's None as a parent, because nodes in the module
        # node have the parent module and not suite as all the others.
        # Therefore it's important to catch that case.
        names = [n for n in names if get_parent_scope(n).parent in (module, None)]
    return names
Exemplo n.º 24
0
        def from_scope_node(scope_node, is_nested=True):
            if scope_node == self.tree_node:
                return self

            if scope_node.type in ('funcdef', 'lambdef', 'classdef'):
                return self.create_value(scope_node).as_context()
            elif scope_node.type in ('comp_for', 'sync_comp_for'):
                parent_scope = parser_utils.get_parent_scope(scope_node)
                parent_context = from_scope_node(parent_scope)
                if node.start_pos >= scope_node.children[-1].start_pos:
                    return parent_context
                return CompForContext(parent_context, scope_node)
            raise Exception("There's a scope that was not managed: %s" % scope_node)
Exemplo n.º 25
0
def _search_function_arguments(module_context, funcdef, string_name):
    """
    Returns a list of param names.
    """
    compare_node = funcdef
    if string_name == '__init__':
        cls = get_parent_scope(funcdef)
        if cls.type == 'classdef':
            string_name = cls.name.value
            compare_node = cls

    found_arguments = False
    i = 0
    inference_state = module_context.inference_state

    if settings.dynamic_params_for_other_modules:
        module_contexts = get_module_contexts_containing_name(
            inference_state,
            [module_context],
            string_name,
            # Limit the amounts of files to be opened massively.
            limit_reduction=5,
        )
    else:
        module_contexts = [module_context]

    for for_mod_context in module_contexts:
        for name, trailer in _get_potential_nodes(for_mod_context,
                                                  string_name):
            i += 1

            # This is a simple way to stop Jedi's dynamic param recursion
            # from going wild: The deeper Jedi's in the recursion, the less
            # code should be inferred.
            if i * inference_state.dynamic_params_depth > MAX_PARAM_SEARCHES:
                return

            random_context = for_mod_context.create_context(name)
            for arguments in _check_name_for_execution(inference_state,
                                                       random_context,
                                                       compare_node, name,
                                                       trailer):
                found_arguments = True
                yield arguments

        # If there are results after processing a module, we're probably
        # good to process. This is a speed optimization.
        if found_arguments:
            return
Exemplo n.º 26
0
    def _check_for_additional_knowledge(self, name_or_str, name_context, position):
        name_context = name_context or self
        # Add isinstance and other if/assert knowledge.
        if isinstance(name_or_str, Name) and not name_context.is_instance():
            flow_scope = name_or_str
            base_nodes = [name_context.tree_node]

            if any(b.type in ('comp_for', 'sync_comp_for') for b in base_nodes):
                return NO_VALUES
            from jedi.inference.finder import check_flow_information
            while True:
                flow_scope = get_parent_scope(flow_scope, include_flows=True)
                n = check_flow_information(name_context, flow_scope,
                                           name_or_str, position)
                if n is not None:
                    return n
                if flow_scope in base_nodes:
                    break
        return NO_VALUES
Exemplo n.º 27
0
 def create_instance_context(self, class_context, node):
     if node.parent.type in ('funcdef', 'classdef'):
         node = node.parent
     scope = get_parent_scope(node)
     if scope == class_context.tree_node:
         return class_context
     else:
         parent_context = self.create_instance_context(class_context, scope)
         if scope.type == 'funcdef':
             if scope.name.value == '__init__' and parent_context == class_context:
                 return self._create_init_execution(class_context, scope)
             else:
                 bound_method = BoundMethod(self.evaluator, self,
                                            class_context,
                                            self.parent_context, scope)
                 return bound_method.get_function_execution()
         else:
             raise NotImplementedError
     return class_context
Exemplo n.º 28
0
 def create_instance_context(self, class_context, node):
     if node.parent.type in ('funcdef', 'classdef'):
         node = node.parent
     scope = get_parent_scope(node)
     if scope == class_context.tree_node:
         return class_context
     else:
         parent_context = self.create_instance_context(class_context, scope)
         if scope.type == 'funcdef':
             if scope.name.value == '__init__' and parent_context == class_context:
                 return self._create_init_execution(class_context, scope)
             else:
                 bound_method = BoundMethod(
                     self.evaluator, self, class_context,
                     self.parent_context, scope
                 )
                 return bound_method.get_function_execution()
         else:
             raise NotImplementedError
     return class_context
Exemplo n.º 29
0
 def is_module_scope_name(name):
     parent_scope = get_parent_scope(name)
     if is_name_of_func_or_class_def(name, parent_scope):
         # XXX: In syntax tree function- and class-name nodes are immediate children of
         # their respective class-definition or function-definition nodes. Technically,
         # get_parent_scope(...) for them should return the parent of the definition node,
         # because
         #
         # def foo(...): pass
         #
         # is equivalent to
         #
         # foo = lambda(...): None
         #
         # but that would be a big change that could break type inference, whereas for now
         # this discrepancy looks like only a problem for "get_module_names".
         parent_scope = parent_scope.parent
     # async functions have an extra wrapper. Strip it.
     if parent_scope and parent_scope.type == 'async_stmt':
         parent_scope = parent_scope.parent
     return parent_scope in (module, None)
Exemplo n.º 30
0
def _search_function_executions(evaluator, module_context, funcdef):
    """
    Returns a list of param names.
    """
    from jedi.evaluate import representation as er

    func_string_name = funcdef.name.value
    compare_node = funcdef
    if func_string_name == '__init__':
        cls = get_parent_scope(funcdef)
        if isinstance(cls, tree.Class):
            func_string_name = cls.name.value
            compare_node = cls

    found_executions = False
    i = 0
    for for_mod_context in imports.get_modules_containing_name(
            evaluator, [module_context], func_string_name):
        if not isinstance(module_context, er.ModuleContext):
            return
        for name, trailer in _get_possible_nodes(for_mod_context,
                                                 func_string_name):
            i += 1

            # This is a simple way to stop Jedi's dynamic param recursion
            # from going wild: The deeper Jedi's in the recursion, the less
            # code should be evaluated.
            if i * evaluator.dynamic_params_depth > MAX_PARAM_SEARCHES:
                return

            random_context = evaluator.create_context(for_mod_context, name)
            for function_execution in _check_name_for_execution(
                    evaluator, random_context, compare_node, name, trailer):
                found_executions = True
                yield function_execution

        # If there are results after processing a module, we're probably
        # good to process. This is a speed optimization.
        if found_executions:
            return
Exemplo n.º 31
0
def _search_function_executions(evaluator, module_context, funcdef):
    """
    Returns a list of param names.
    """
    from jedi.evaluate import representation as er

    func_string_name = funcdef.name.value
    compare_node = funcdef
    if func_string_name == '__init__':
        cls = get_parent_scope(funcdef)
        if isinstance(cls, tree.Class):
            func_string_name = cls.name.value
            compare_node = cls

    found_executions = False
    i = 0
    for for_mod_context in imports.get_modules_containing_name(
            evaluator, [module_context], func_string_name):
        if not isinstance(module_context, er.ModuleContext):
            return
        for name, trailer in _get_possible_nodes(for_mod_context, func_string_name):
            i += 1

            # This is a simple way to stop Jedi's dynamic param recursion
            # from going wild: The deeper Jedi's in the recursion, the less
            # code should be evaluated.
            if i * evaluator.dynamic_params_depth > MAX_PARAM_SEARCHES:
                return

            random_context = evaluator.create_context(for_mod_context, name)
            for function_execution in _check_name_for_execution(
                    evaluator, random_context, compare_node, name, trailer):
                found_executions = True
                yield function_execution

        # If there are results after processing a module, we're probably
        # good to process. This is a speed optimization.
        if found_executions:
            return
Exemplo n.º 32
0
def tree_name_to_values(inference_state, context, tree_name):
    value_set = NO_VALUES
    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, [])
        found_annotation = False
        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:
                    found_annotation = True
                    value_set |= annotation.infer_annotation(
                        context,
                        expr_stmt.children[1].children[1]).execute_annotation(
                        )
        if found_annotation:
            return value_set

    types = []
    node = tree_name.get_definition(import_name_always=True,
                                    include_setitem=True)
    if node is None:
        node = tree_name.parent
        if node.type == 'global_stmt':
            c = context.create_context(tree_name)
            if c.is_module():
                # In case we are already part of the module, there is no point
                # in looking up the global statement anymore, because it's not
                # valid at that point anyway.
                return NO_VALUES
            # For global_stmt lookups, we only need the first possible scope,
            # which means the function itself.
            filter = next(c.get_filters())
            names = filter.get(tree_name.value)
            return ValueSet.from_sets(name.infer() for name in names)
        elif node.type not in ('import_from', 'import_name'):
            c = context.create_context(tree_name)
            return infer_atom(c, 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_values(
                cn.infer(),
                contextualized_node=cn,
                is_async=node.parent.type == 'async_stmt',
            )
            n = TreeNameDefinition(context, tree_name)
            types = check_tuple_assignments(n, for_types)
    elif typ == 'expr_stmt':
        types = infer_expr_stmt(context, node, tree_name)
    elif typ == 'with_stmt':
        value_managers = context.infer_node(
            node.get_test_node_from_name(tree_name))
        if node.parent.type == 'async_stmt':
            # In the case of `async with` statements, we need to
            # first get the coroutine from the `__aenter__` method,
            # then "unwrap" via the `__await__` method
            enter_methods = value_managers.py__getattribute__('__aenter__')
            coro = enter_methods.execute_with_values()
            return coro.py__await__().py__stop_iteration_returns()
        enter_methods = value_managers.py__getattribute__('__enter__')
        return enter_methods.execute_with_values()
    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.infer_node(
            tree_name.get_previous_sibling().get_previous_sibling())
        types = exceptions.execute_with_values()
    elif typ == 'param':
        types = NO_VALUES
    elif typ == 'del_stmt':
        types = NO_VALUES
    elif typ == 'namedexpr_test':
        types = infer_node(context, node)
    else:
        raise ValueError("Should not happen. type: %s" % typ)
    return types
Exemplo n.º 33
0
def _get_flow_scopes(node):
    while True:
        node = get_parent_scope(node, include_flows=True)
        if node is None or is_scope(node):
            return
        yield node
Exemplo n.º 34
0
def _get_flow_scopes(node):
    while True:
        node = get_parent_scope(node, include_flows=True)
        if node is None or is_scope(node):
            return
        yield node
Exemplo n.º 35
0
 def is_module_scope_name(name):
     parent_scope = get_parent_scope(name)
     # async functions have an extra wrapper. Strip it.
     if parent_scope and parent_scope.type == 'async_stmt':
         parent_scope = parent_scope.parent
     return parent_scope in (module, None)
Exemplo n.º 36
0
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
Exemplo n.º 37
0
 def create_instance_context(self, class_context, node):
     if get_parent_scope(node).type == 'classdef':
         return class_context
     else:
         return super(CompiledInstance, self).create_instance_context(class_context, node)
Exemplo n.º 38
0
 def create_instance_context(self, class_context, node):
     if get_parent_scope(node).type == 'classdef':
         return class_context
     else:
         return super(CompiledInstance,
                      self).create_instance_context(class_context, node)
Exemplo n.º 39
0
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