Exemplo n.º 1
0
def import_module(evaluator, import_names, parent_module_context, sys_path):
    """
    This method is very similar to importlib's `_gcd_import`.
    """
    if import_names[0] in settings.auto_import_modules:
        module = _load_builtin_module(evaluator, import_names, sys_path)
        if module is None:
            return NO_CONTEXTS
        return ContextSet([module])

    module_name = '.'.join(import_names)
    if parent_module_context is None:
        # Override the sys.path. It works only good that way.
        # Injecting the path directly into `find_module` did not work.
        file_io_or_ns, is_pkg = evaluator.compiled_subprocess.get_module_info(
            string=import_names[-1],
            full_name=module_name,
            sys_path=sys_path,
            is_global_search=True,
        )
        if is_pkg is None:
            return NO_CONTEXTS
    else:
        try:
            method = parent_module_context.py__path__
        except AttributeError:
            # The module is not a package.
            return NO_CONTEXTS
        else:
            paths = method()
            for path in paths:
                # At the moment we are only using one path. So this is
                # not important to be correct.
                if not isinstance(path, list):
                    path = [path]
                file_io_or_ns, is_pkg = evaluator.compiled_subprocess.get_module_info(
                    string=import_names[-1],
                    path=path,
                    full_name=module_name,
                    is_global_search=False,
                )
                if is_pkg is not None:
                    break
            else:
                return NO_CONTEXTS

    if isinstance(file_io_or_ns, ImplicitNSInfo):
        from jedi.evaluate.context.namespace import ImplicitNamespaceContext
        module = ImplicitNamespaceContext(
            evaluator,
            fullname=file_io_or_ns.name,
            paths=file_io_or_ns.paths,
        )
    elif file_io_or_ns is None:
        module = _load_builtin_module(evaluator, import_names, sys_path)
        if module is None:
            return NO_CONTEXTS
    else:
        module = _load_python_module(
            evaluator, file_io_or_ns, sys_path,
            import_names=import_names,
            is_package=is_pkg,
        )

    if parent_module_context is None:
        debug.dbg('global search_module %s: %s', import_names[-1], module)
    else:
        debug.dbg('search_module %s in paths %s: %s', module_name, paths, module)
    return ContextSet([module])
Exemplo n.º 2
0
 def infer(self):
     return ContextSet(self._instance)
Exemplo n.º 3
0
def eval_node(context, element):
    debug.dbg('eval_node %s@%s in %s', element, element.start_pos, context)
    evaluator = context.evaluator
    typ = element.type
    if typ in ('name', 'number', 'string', 'atom', 'strings', 'keyword',
               'fstring'):
        return eval_atom(context, element)
    elif typ == 'lambdef':
        return ContextSet([FunctionContext.from_context(context, element)])
    elif typ == 'expr_stmt':
        return eval_expr_stmt(context, element)
    elif typ in ('power', 'atom_expr'):
        first_child = element.children[0]
        children = element.children[1:]
        had_await = False
        if first_child.type == 'keyword' and first_child.value == 'await':
            had_await = True
            first_child = children.pop(0)

        context_set = context.eval_node(first_child)
        for (i, trailer) in enumerate(children):
            if trailer == '**':  # has a power operation.
                right = context.eval_node(children[i + 1])
                context_set = _eval_comparison(evaluator, context, context_set,
                                               trailer, right)
                break
            context_set = eval_trailer(context, context_set, trailer)

        if had_await:
            return context_set.py__await__().py__stop_iteration_returns()
        return context_set
    elif typ in (
            'testlist_star_expr',
            'testlist',
    ):
        # The implicit tuple in statements.
        return ContextSet(
            [iterable.SequenceLiteralContext(evaluator, context, element)])
    elif typ in ('not_test', 'factor'):
        context_set = context.eval_node(element.children[-1])
        for operator in element.children[:-1]:
            context_set = eval_factor(context_set, operator)
        return context_set
    elif typ == 'test':
        # `x if foo else y` case.
        return (context.eval_node(element.children[0])
                | context.eval_node(element.children[-1]))
    elif typ == 'operator':
        # Must be an ellipsis, other operators are not evaluated.
        # In Python 2 ellipsis is coded as three single dot tokens, not
        # as one token 3 dot token.
        if element.value not in ('.', '...'):
            origin = element.parent
            raise AssertionError("unhandled operator %s in %s " %
                                 (repr(element.value), origin))
        return ContextSet([compiled.builtin_from_name(evaluator, u'Ellipsis')])
    elif typ == 'dotted_name':
        context_set = eval_atom(context, element.children[0])
        for next_name in element.children[2::2]:
            # TODO add search_global=True?
            context_set = context_set.py__getattribute__(next_name,
                                                         name_context=context)
        return context_set
    elif typ == 'eval_input':
        return eval_node(context, element.children[0])
    elif typ == 'annassign':
        return annotation.eval_annotation(context, element.children[1]) \
            .execute_annotation()
    elif typ == 'yield_expr':
        if len(element.children) and element.children[1].type == 'yield_arg':
            # Implies that it's a yield from.
            element = element.children[1].children[1]
            generators = context.eval_node(element) \
                .py__getattribute__('__iter__').execute_evaluated()
            return generators.py__stop_iteration_returns()

        # Generator.send() is not implemented.
        return NO_CONTEXTS
    else:
        return eval_or_test(context, element)
Exemplo n.º 4
0
def eval_atom(context, atom):
    """
    Basically to process ``atom`` nodes. The parser sometimes doesn't
    generate the node (because it has just one child). In that case an atom
    might be a name or a literal as well.
    """
    if atom.type == 'name':
        # This is the first global lookup.
        stmt = tree.search_ancestor(atom, 'expr_stmt', 'lambdef') or atom
        if stmt.type == 'lambdef':
            stmt = atom
        return context.py__getattribute__(name_or_str=atom,
                                          position=stmt.start_pos,
                                          search_global=True)

    elif isinstance(atom, tree.Literal):
        string = parser_utils.safe_literal_eval(atom.value)
        return ContextSet(compiled.create(context.evaluator, string))
    else:
        c = atom.children
        if c[0].type == 'string':
            # Will be one string.
            context_set = eval_atom(context, c[0])
            for string in c[1:]:
                right = eval_atom(context, string)
                context_set = _eval_comparison(context.evaluator, context,
                                               context_set, '+', right)
            return context_set
        # Parentheses without commas are not tuples.
        elif c[0] == '(' and not len(c) == 2 \
                and not(c[1].type == 'testlist_comp' and
                        len(c[1].children) > 1):
            return context.eval_node(c[1])

        try:
            comp_for = c[1].children[1]
        except (IndexError, AttributeError):
            pass
        else:
            if comp_for == ':':
                # Dict comprehensions have a colon at the 3rd index.
                try:
                    comp_for = c[1].children[3]
                except IndexError:
                    pass

            if comp_for.type == 'comp_for':
                return ContextSet(
                    iterable.Comprehension.from_atom(context.evaluator,
                                                     context, atom))

        # It's a dict/list/tuple literal.
        array_node = c[1]
        try:
            array_node_c = array_node.children
        except AttributeError:
            array_node_c = []
        if c[0] == '{' and (array_node == '}' or ':' in array_node_c):
            context = iterable.DictLiteralContext(context.evaluator, context,
                                                  atom)
        else:
            context = iterable.SequenceLiteralContext(context.evaluator,
                                                      context, atom)
        return ContextSet(context)
Exemplo n.º 5
0
 def infer(self):
     return ContextSet([self._context])
Exemplo n.º 6
0
 def py__stop_iteration_returns(self):
     return ContextSet(compiled.builtin_from_name(self.evaluator, u'None'))
Exemplo n.º 7
0
def _check_array_additions(context, sequence):
    """
    Checks if a `Array` has "add" (append, insert, extend) statements:

    >>> a = [""]
    >>> a.append(1)
    """
    from jedi.evaluate import arguments

    debug.dbg('Dynamic array search for %s' % sequence, color='MAGENTA')
    module_context = context.get_root_context()
    if not settings.dynamic_array_additions or isinstance(
            module_context, compiled.CompiledObject):
        debug.dbg('Dynamic array search aborted.', color='MAGENTA')
        return ContextSet()

    def find_additions(context, arglist, add_name):
        params = list(
            arguments.TreeArguments(context.evaluator, context,
                                    arglist).unpack())
        result = set()
        if add_name in ['insert']:
            params = params[1:]
        if add_name in ['append', 'add', 'insert']:
            for key, whatever in params:
                result.add(whatever)
        elif add_name in ['extend', 'update']:
            for key, lazy_context in params:
                result |= set(lazy_context.infer().iterate())
        return result

    temp_param_add, settings.dynamic_params_for_other_modules = \
        settings.dynamic_params_for_other_modules, False

    is_list = sequence.name.string_name == 'list'
    search_names = (['append', 'extend', 'insert']
                    if is_list else ['add', 'update'])

    added_types = set()
    for add_name in search_names:
        try:
            possible_names = module_context.tree_node.get_used_names(
            )[add_name]
        except KeyError:
            continue
        else:
            for name in possible_names:
                context_node = context.tree_node
                if not (context_node.start_pos < name.start_pos <
                        context_node.end_pos):
                    continue
                trailer = name.parent
                power = trailer.parent
                trailer_pos = power.children.index(trailer)
                try:
                    execution_trailer = power.children[trailer_pos + 1]
                except IndexError:
                    continue
                else:
                    if execution_trailer.type != 'trailer' \
                            or execution_trailer.children[0] != '(' \
                            or execution_trailer.children[1] == ')':
                        continue

                random_context = context.create_context(name)

                with recursion.execution_allowed(context.evaluator,
                                                 power) as allowed:
                    if allowed:
                        found = evaluate_call_of_leaf(random_context,
                                                      name,
                                                      cut_own_trailer=True)
                        if sequence in found:
                            # The arrays match. Now add the results
                            added_types |= find_additions(
                                random_context, execution_trailer.children[1],
                                add_name)

    # reset settings
    settings.dynamic_params_for_other_modules = temp_param_add
    debug.dbg('Dynamic array result %s' % added_types, color='MAGENTA')
    return added_types
Exemplo n.º 8
0
    def _do_import(self, import_path, sys_path):
        """
        This method is very similar to importlib's `_gcd_import`.
        """
        import_parts = [
            force_unicode(i.value if isinstance(i, tree.Name) else i)
            for i in import_path
        ]

        # Handle "magic" Flask extension imports:
        # ``flask.ext.foo`` is really ``flask_foo`` or ``flaskext.foo``.
        if len(import_path) > 2 and import_parts[:2] == ['flask', 'ext']:
            # New style.
            ipath = ('flask_' + str(import_parts[2]), ) + import_path[3:]
            modules = self._do_import(ipath, sys_path)
            if modules:
                return modules
            else:
                # Old style
                return self._do_import(('flaskext', ) + import_path[2:],
                                       sys_path)

        module_name = '.'.join(import_parts)
        try:
            return ContextSet(self._evaluator.module_cache.get(module_name))
        except KeyError:
            pass

        if len(import_path) > 1:
            # This is a recursive way of importing that works great with
            # the module cache.
            bases = self._do_import(import_path[:-1], sys_path)
            if not bases:
                return NO_CONTEXTS
            # We can take the first element, because only the os special
            # case yields multiple modules, which is not important for
            # further imports.
            parent_module = list(bases)[0]

            # This is a huge exception, we follow a nested import
            # ``os.path``, because it's a very important one in Python
            # that is being achieved by messing with ``sys.modules`` in
            # ``os``.
            if import_parts == ['os', 'path']:
                return parent_module.py__getattribute__('path')

            try:
                method = parent_module.py__path__
            except AttributeError:
                # The module is not a package.
                _add_error(self.module_context, import_path[-1])
                return NO_CONTEXTS
            else:
                paths = method()
                debug.dbg('search_module %s in paths %s', module_name, paths)
                for path in paths:
                    # At the moment we are only using one path. So this is
                    # not important to be correct.
                    if not isinstance(path, list):
                        path = [path]
                    code, module_path, is_pkg = self._evaluator.compiled_subprocess.get_module_info(
                        string=import_parts[-1],
                        path=path,
                        full_name=module_name)
                    if module_path is not None:
                        break
                else:
                    _add_error(self.module_context, import_path[-1])
                    return NO_CONTEXTS
        else:
            debug.dbg('search_module %s in %s', import_parts[-1],
                      self.file_path)
            # Override the sys.path. It works only good that way.
            # Injecting the path directly into `find_module` did not work.
            code, module_path, is_pkg = self._evaluator.compiled_subprocess.get_module_info(
                string=import_parts[-1],
                full_name=module_name,
                sys_path=sys_path,
            )
            if module_path is None:
                # The module is not a package.
                _add_error(self.module_context, import_path[-1])
                return NO_CONTEXTS

        module = _load_module(
            self._evaluator,
            module_path,
            code,
            sys_path,
            module_name=module_name,
            safe_module_name=True,
        )

        if module is None:
            # The file might raise an ImportError e.g. and therefore not be
            # importable.
            return NO_CONTEXTS

        return ContextSet(module)
Exemplo n.º 9
0
    def eval_element(self, context, element):
        if isinstance(context, CompForContext):
            return eval_node(context, element)

        if_stmt = element
        while if_stmt is not None:
            if_stmt = if_stmt.parent
            if if_stmt.type in ('if_stmt', 'for_stmt'):
                break
            if parser_utils.is_scope(if_stmt):
                if_stmt = None
                break
        predefined_if_name_dict = context.predefined_names.get(if_stmt)
        # TODO there's a lot of issues with this one. We actually should do
        # this in a different way. Caching should only be active in certain
        # cases and this all sucks.
        if predefined_if_name_dict is None and if_stmt \
                and if_stmt.type == 'if_stmt' and self.is_analysis:
            if_stmt_test = if_stmt.children[1]
            name_dicts = [{}]
            # If we already did a check, we don't want to do it again -> If
            # context.predefined_names is filled, we stop.
            # We don't want to check the if stmt itself, it's just about
            # the content.
            if element.start_pos > if_stmt_test.end_pos:
                # Now we need to check if the names in the if_stmt match the
                # names in the suite.
                if_names = helpers.get_names_of_node(if_stmt_test)
                element_names = helpers.get_names_of_node(element)
                str_element_names = [e.value for e in element_names]
                if any(i.value in str_element_names for i in if_names):
                    for if_name in if_names:
                        definitions = self.goto_definitions(context, if_name)
                        # Every name that has multiple different definitions
                        # causes the complexity to rise. The complexity should
                        # never fall below 1.
                        if len(definitions) > 1:
                            if len(name_dicts) * len(definitions) > 16:
                                debug.dbg(
                                    'Too many options for if branch evaluation %s.',
                                    if_stmt)
                                # There's only a certain amount of branches
                                # Jedi can evaluate, otherwise it will take to
                                # long.
                                name_dicts = [{}]
                                break

                            original_name_dicts = list(name_dicts)
                            name_dicts = []
                            for definition in definitions:
                                new_name_dicts = list(original_name_dicts)
                                for i, name_dict in enumerate(new_name_dicts):
                                    new_name_dicts[i] = name_dict.copy()
                                    new_name_dicts[i][
                                        if_name.value] = ContextSet(definition)

                                name_dicts += new_name_dicts
                        else:
                            for name_dict in name_dicts:
                                name_dict[if_name.value] = definitions
            if len(name_dicts) > 1:
                result = ContextSet()
                for name_dict in name_dicts:
                    with helpers.predefine_names(context, if_stmt, name_dict):
                        result |= eval_node(context, element)
                return result
            else:
                return self._eval_element_if_evaluated(context, element)
        else:
            if predefined_if_name_dict:
                return eval_node(context, element)
            else:
                return self._eval_element_if_evaluated(context, element)
Exemplo n.º 10
0
 def py__getitem__(self, index_context_set, contextualized_node):
     if self.array_type == 'dict':
         return self._dict_values()
     return iterate_contexts(ContextSet([self]))
Exemplo n.º 11
0
 def py__iter__(self, contextualized_node=None):
     return ContextSet([self])
Exemplo n.º 12
0
 def iterate():
     if isinstance(maybe_tuple_context, SequenceLiteralContext):
         for lazy_context in maybe_tuple_context.py__iter__(contextualized_node=None):
             yield lazy_context.infer()
     else:
         yield ContextSet([maybe_tuple_context])
Exemplo n.º 13
0
 def infer(self):
     return ContextSet()
Exemplo n.º 14
0
 def infer(self):
     module = self.parent_context.get_root_context()
     return ContextSet(
         _create_from_name(self._evaluator, module, self.parent_context,
                           self.string_name))
Exemplo n.º 15
0
    def py__getitem__(self, index):
        if isinstance(index, slice):
            return ContextSet(self)

        all_types = list(self.py__iter__())
        return all_types[index].infer()
Exemplo n.º 16
0
def get_dynamic_array_instance(instance, arguments):
    """Used for set() and list() instances."""
    ai = _ArrayInstance(instance, arguments)
    from jedi.evaluate import arguments
    return arguments.ValuesArguments([ContextSet(ai)])
Exemplo n.º 17
0
 def _imitate_values(self):
     lazy_context = LazyKnownContexts(self.dict_values())
     return ContextSet(FakeSequence(self.evaluator, u'list',
                                    [lazy_context]))
Exemplo n.º 18
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.º 19
0
 def _values(self):
     return ContextSet(
         FakeSequence(self.evaluator, u'tuple',
                      [LazyKnownContexts(self.dict_values())]))
Exemplo n.º 20
0
 def py__call__(self, arguments):
     instance, = super(AbstractAnnotatedClass, self).py__call__(arguments)
     return ContextSet([InstanceWrapper(instance)])
Exemplo n.º 21
0
    def _do_import(self, import_path, sys_path):
        """
        This method is very similar to importlib's `_gcd_import`.
        """
        import_parts = [
            i.value if isinstance(i, tree.Name) else i for i in import_path
        ]

        # Handle "magic" Flask extension imports:
        # ``flask.ext.foo`` is really ``flask_foo`` or ``flaskext.foo``.
        if len(import_path) > 2 and import_parts[:2] == ['flask', 'ext']:
            # New style.
            ipath = ('flask_' + str(import_parts[2]), ) + import_path[3:]
            modules = self._do_import(ipath, sys_path)
            if modules:
                return modules
            else:
                # Old style
                return self._do_import(('flaskext', ) + import_path[2:],
                                       sys_path)

        module_name = '.'.join(import_parts)
        try:
            return ContextSet(self._evaluator.modules[module_name])
        except KeyError:
            pass

        if len(import_path) > 1:
            # This is a recursive way of importing that works great with
            # the module cache.
            bases = self._do_import(import_path[:-1], sys_path)
            if not bases:
                return NO_CONTEXTS
            # We can take the first element, because only the os special
            # case yields multiple modules, which is not important for
            # further imports.
            parent_module = list(bases)[0]

            # This is a huge exception, we follow a nested import
            # ``os.path``, because it's a very important one in Python
            # that is being achieved by messing with ``sys.modules`` in
            # ``os``.
            if import_parts == ['os', 'path']:
                return parent_module.py__getattribute__('path')

            try:
                method = parent_module.py__path__
            except AttributeError:
                # The module is not a package.
                _add_error(self.module_context, import_path[-1])
                return NO_CONTEXTS
            else:
                paths = method()
                debug.dbg('search_module %s in paths %s', module_name, paths)
                for path in paths:
                    # At the moment we are only using one path. So this is
                    # not important to be correct.
                    try:
                        if not isinstance(path, list):
                            path = [path]
                        module_file, module_path, is_pkg = \
                            find_module(import_parts[-1], path, fullname=module_name)
                        break
                    except ImportError:
                        module_path = None
                if module_path is None:
                    _add_error(self.module_context, import_path[-1])
                    return NO_CONTEXTS
        else:
            parent_module = None
            try:
                debug.dbg('search_module %s in %s', import_parts[-1],
                          self.file_path)
                # Override the sys.path. It works only good that way.
                # Injecting the path directly into `find_module` did not work.
                sys.path, temp = sys_path, sys.path
                try:
                    module_file, module_path, is_pkg = \
                        find_module(import_parts[-1], fullname=module_name)
                finally:
                    sys.path = temp
            except ImportError:
                # The module is not a package.
                _add_error(self.module_context, import_path[-1])
                return NO_CONTEXTS

        code = None
        if is_pkg:
            # In this case, we don't have a file yet. Search for the
            # __init__ file.
            if module_path.endswith(('.zip', '.egg')):
                code = module_file.loader.get_source(module_name)
            else:
                module_path = get_init_path(module_path)
        elif module_file:
            code = module_file.read()
            module_file.close()

        if isinstance(module_path, ImplicitNSInfo):
            from jedi.evaluate.context.namespace import ImplicitNamespaceContext
            fullname, paths = module_path.name, module_path.paths
            module = ImplicitNamespaceContext(self._evaluator,
                                              fullname=fullname)
            module.paths = paths
        elif module_file is None and not module_path.endswith(
            ('.py', '.zip', '.egg')):
            module = compiled.load_module(self._evaluator, module_path)
        else:
            module = _load_module(self._evaluator, module_path, code, sys_path,
                                  parent_module)

        if module is None:
            # The file might raise an ImportError e.g. and therefore not be
            # importable.
            return NO_CONTEXTS

        self._evaluator.modules[module_name] = module
        return ContextSet(module)
Exemplo n.º 22
0
 def infer(self):
     return ContextSet(self._remap())
Exemplo n.º 23
0
def eval_node(context, element):
    debug.dbg('eval_element %s@%s', element, element.start_pos)
    evaluator = context.evaluator
    typ = element.type
    if typ in ('name', 'number', 'string', 'atom'):
        return eval_atom(context, element)
    elif typ == 'keyword':
        # For False/True/None
        if element.value in ('False', 'True', 'None'):
            return ContextSet(
                compiled.builtin_from_name(evaluator, element.value))
        # else: print e.g. could be evaluated like this in Python 2.7
        return NO_CONTEXTS
    elif typ == 'lambdef':
        return ContextSet(FunctionContext(evaluator, context, element))
    elif typ == 'expr_stmt':
        return eval_expr_stmt(context, element)
    elif typ in ('power', 'atom_expr'):
        first_child = element.children[0]
        if not (first_child.type == 'keyword'
                and first_child.value == 'await'):
            context_set = eval_atom(context, first_child)
            for trailer in element.children[1:]:
                if trailer == '**':  # has a power operation.
                    right = evaluator.eval_element(context,
                                                   element.children[2])
                    context_set = _eval_comparison(evaluator, context,
                                                   context_set, trailer, right)
                    break
                context_set = eval_trailer(context, context_set, trailer)
            return context_set
        return NO_CONTEXTS
    elif typ in (
            'testlist_star_expr',
            'testlist',
    ):
        # The implicit tuple in statements.
        return ContextSet(
            iterable.SequenceLiteralContext(evaluator, context, element))
    elif typ in ('not_test', 'factor'):
        context_set = context.eval_node(element.children[-1])
        for operator in element.children[:-1]:
            context_set = eval_factor(context_set, operator)
        return context_set
    elif typ == 'test':
        # `x if foo else y` case.
        return (context.eval_node(element.children[0])
                | context.eval_node(element.children[-1]))
    elif typ == 'operator':
        # Must be an ellipsis, other operators are not evaluated.
        # In Python 2 ellipsis is coded as three single dot tokens, not
        # as one token 3 dot token.
        assert element.value in ('.', '...')
        return ContextSet(compiled.create(evaluator, Ellipsis))
    elif typ == 'dotted_name':
        context_set = eval_atom(context, element.children[0])
        for next_name in element.children[2::2]:
            # TODO add search_global=True? id:489 gh:490
            context_set = context_set.py__getattribute__(next_name,
                                                         name_context=context)
        return context_set
    elif typ == 'eval_input':
        return eval_node(context, element.children[0])
    elif typ == 'annassign':
        return pep0484._evaluate_for_annotation(context, element.children[1])
    else:
        return eval_or_test(context, element)
Exemplo n.º 24
0
 def infer(self):
     return ContextSet(self.parent_context)
Exemplo n.º 25
0
 def infer(self):
     return ContextSet(self.data)
Exemplo n.º 26
0
 def goto(self):
     return ContextSet([self._context.name])
Exemplo n.º 27
0
def _eval_comparison_part(evaluator, context, left, operator, right):
    l_is_num = is_number(left)
    r_is_num = is_number(right)
    if isinstance(operator, unicode):
        str_operator = operator
    else:
        str_operator = force_unicode(str(operator.value))

    if str_operator == '*':
        # for iterables, ignore * operations
        if isinstance(left, iterable.Sequence) or is_string(left):
            return ContextSet([left])
        elif isinstance(right, iterable.Sequence) or is_string(right):
            return ContextSet([right])
    elif str_operator == '+':
        if l_is_num and r_is_num or is_string(left) and is_string(right):
            return ContextSet([left.execute_operation(right, str_operator)])
        elif _is_tuple(left) and _is_tuple(right) or _is_list(
                left) and _is_list(right):
            return ContextSet([iterable.MergedArray(evaluator, (left, right))])
    elif str_operator == '-':
        if l_is_num and r_is_num:
            return ContextSet([left.execute_operation(right, str_operator)])
    elif str_operator == '%':
        # With strings and numbers the left type typically remains. Except for
        # `int() % float()`.
        return ContextSet([left])
    elif str_operator in COMPARISON_OPERATORS:
        if left.is_compiled() and right.is_compiled():
            # Possible, because the return is not an option. Just compare.
            try:
                return ContextSet(
                    [left.execute_operation(right, str_operator)])
            except TypeError:
                # Could be True or False.
                pass
        else:
            if str_operator in ('is', '!=', '==', 'is not'):
                operation = COMPARISON_OPERATORS[str_operator]
                bool_ = operation(left, right)
                return ContextSet([_bool_to_context(evaluator, bool_)])

            if isinstance(left, VersionInfo):
                version_info = _get_tuple_ints(right)
                if version_info is not None:
                    bool_result = compiled.access.COMPARISON_OPERATORS[
                        operator](evaluator.environment.version_info,
                                  tuple(version_info))
                    return ContextSet(
                        [_bool_to_context(evaluator, bool_result)])

        return ContextSet([
            _bool_to_context(evaluator, True),
            _bool_to_context(evaluator, False)
        ])
    elif str_operator == 'in':
        return NO_CONTEXTS

    def check(obj):
        """Checks if a Jedi object is either a float or an int."""
        return isinstance(obj, TreeInstance) and \
            obj.name.string_name in ('int', 'float')

    # Static analysis, one is a number, the other one is not.
    if str_operator in ('+', '-') and l_is_num != r_is_num \
            and not (check(left) or check(right)):
        message = "TypeError: unsupported operand type(s) for +: %s and %s"
        analysis.add(context, 'type-error-operation', operator,
                     message % (left, right))

    result = ContextSet([left, right])
    debug.dbg('Used operator %s resulting in %s', operator, result)
    return result
Exemplo n.º 28
0
 def infer(self):
     return ContextSet([
         _create_from_name(self._evaluator, self.parent_context,
                           self.string_name)
     ])
Exemplo n.º 29
0
def eval_atom(context, atom):
    """
    Basically to process ``atom`` nodes. The parser sometimes doesn't
    generate the node (because it has just one child). In that case an atom
    might be a name or a literal as well.
    """
    if atom.type == 'name':
        # This is the first global lookup.
        stmt = tree.search_ancestor(atom, 'expr_stmt', 'lambdef') or atom
        if stmt.type == 'lambdef':
            stmt = atom
        return context.py__getattribute__(name_or_str=atom,
                                          position=stmt.start_pos,
                                          search_global=True)
    elif atom.type == 'keyword':
        # For False/True/None
        if atom.value in ('False', 'True', 'None'):
            return ContextSet(
                compiled.builtin_from_name(context.evaluator, atom.value))
        elif atom.value == 'print':
            # print e.g. could be evaluated like this in Python 2.7
            return NO_CONTEXTS
        elif atom.value == 'yield':
            # Contrary to yield from, yield can just appear alone to return a
            # value when used with `.send()`.
            return NO_CONTEXTS
        assert False, 'Cannot evaluate the keyword %s' % atom

    elif isinstance(atom, tree.Literal):
        string = context.evaluator.compiled_subprocess.safe_literal_eval(
            atom.value)
        return ContextSet(
            compiled.create_simple_object(context.evaluator, string))
    elif atom.type == 'strings':
        # Will be multiple string.
        context_set = eval_atom(context, atom.children[0])
        for string in atom.children[1:]:
            right = eval_atom(context, string)
            context_set = _eval_comparison(context.evaluator, context,
                                           context_set, u'+', right)
        return context_set
    else:
        c = atom.children
        # Parentheses without commas are not tuples.
        if c[0] == '(' and not len(c) == 2 \
                and not(c[1].type == 'testlist_comp' and
                        len(c[1].children) > 1):
            return context.eval_node(c[1])

        try:
            comp_for = c[1].children[1]
        except (IndexError, AttributeError):
            pass
        else:
            if comp_for == ':':
                # Dict comprehensions have a colon at the 3rd index.
                try:
                    comp_for = c[1].children[3]
                except IndexError:
                    pass

            if comp_for.type == 'comp_for':
                return ContextSet(
                    iterable.comprehension_from_atom(context.evaluator,
                                                     context, atom))

        # It's a dict/list/tuple literal.
        array_node = c[1]
        try:
            array_node_c = array_node.children
        except AttributeError:
            array_node_c = []
        if c[0] == '{' and (array_node == '}' or ':' in array_node_c):
            context = iterable.DictLiteralContext(context.evaluator, context,
                                                  atom)
        else:
            context = iterable.SequenceLiteralContext(context.evaluator,
                                                      context, atom)
        return ContextSet(context)
Exemplo n.º 30
0
 def py__call__(self, arguments):
     from jedi.evaluate.context import TreeInstance
     return ContextSet([
         TreeInstance(self.evaluator, self.parent_context, self, arguments)
     ])