Esempio n. 1
0
def _load_python_module(inference_state,
                        file_io,
                        sys_path=None,
                        import_names=None,
                        is_package=False):
    try:
        return inference_state.module_cache.get_from_path(file_io.path)
    except KeyError:
        pass

    module_node = inference_state.parse(file_io=file_io,
                                        cache=True,
                                        diff_cache=settings.fast_parser,
                                        cache_path=settings.cache_directory)

    from jedi.inference.value import ModuleValue
    return ModuleValue(
        inference_state,
        module_node,
        file_io=file_io,
        string_names=import_names,
        code_lines=get_cached_code_lines(inference_state.grammar,
                                         file_io.path),
        is_package=is_package,
    )
Esempio n. 2
0
def _load_module(evaluator,
                 path=None,
                 code=None,
                 sys_path=None,
                 import_names=None,
                 safe_module_name=False):
    if import_names is None:
        dotted_name = None
    else:
        dotted_name = '.'.join(import_names)
    try:
        return evaluator.module_cache.get(dotted_name)
    except KeyError:
        pass
    try:
        return evaluator.module_cache.get_from_path(path)
    except KeyError:
        pass

    if isinstance(path, ImplicitNSInfo):
        from jedi.evaluate.context.namespace import ImplicitNamespaceContext
        module = ImplicitNamespaceContext(
            evaluator,
            fullname=path.name,
            paths=path.paths,
        )
    else:
        if sys_path is None:
            sys_path = evaluator.get_sys_path()

        if path is not None and path.endswith(('.py', '.zip', '.egg')):
            module_node = evaluator.parse(code=code,
                                          path=path,
                                          cache=True,
                                          diff_cache=settings.fast_parser,
                                          cache_path=settings.cache_directory)

            from jedi.evaluate.context import ModuleContext
            module = ModuleContext(
                evaluator,
                module_node,
                path=path,
                code_lines=get_cached_code_lines(evaluator.grammar, path),
            )
        else:
            assert dotted_name is not None
            module = compiled.load_module(evaluator,
                                          dotted_name=dotted_name,
                                          sys_path=sys_path)

    if module is not None and dotted_name is not None:
        add_module_to_cache(evaluator,
                            dotted_name,
                            module,
                            safe=safe_module_name)

    return module
Esempio n. 3
0
def create_stub_module(inference_state, python_value_set, stub_module_node, file_io, import_names):
    if import_names == ('typing',):
        module_cls = TypingModuleWrapper
    else:
        module_cls = StubModuleValue
    file_name = os.path.basename(file_io.path)
    stub_module_value = module_cls(
        python_value_set, inference_state, stub_module_node,
        file_io=file_io,
        string_names=import_names,
        # The code was loaded with latest_grammar, so use
        # that.
        code_lines=get_cached_code_lines(inference_state.latest_grammar, file_io.path),
        is_package=file_name == '__init__.pyi',
    )
    return stub_module_value
Esempio n. 4
0
def _load_module(evaluator, path=None, code=None, sys_path=None,
                 import_names=None, safe_module_name=False):
    if import_names is None:
        dotted_name = None
    else:
        dotted_name = '.'.join(import_names)
    try:
        return evaluator.module_cache.get(dotted_name)
    except KeyError:
        pass
    try:
        return evaluator.module_cache.get_from_path(path)
    except KeyError:
        pass

    if isinstance(path, ImplicitNSInfo):
        from jedi.evaluate.context.namespace import ImplicitNamespaceContext
        module = ImplicitNamespaceContext(
            evaluator,
            fullname=path.name,
            paths=path.paths,
        )
    else:
        if sys_path is None:
            sys_path = evaluator.get_sys_path()

        if path is not None and path.endswith(('.py', '.zip', '.egg')):
            module_node = evaluator.parse(
                code=code, path=path, cache=True,
                diff_cache=settings.fast_parser,
                cache_path=settings.cache_directory)

            from jedi.evaluate.context import ModuleContext
            module = ModuleContext(
                evaluator, module_node,
                path=path,
                code_lines=get_cached_code_lines(evaluator.grammar, path),
            )
        else:
            assert dotted_name is not None
            module = compiled.load_module(evaluator, dotted_name=dotted_name, sys_path=sys_path)

    if module is not None and dotted_name is not None:
        add_module_to_cache(evaluator, dotted_name, module, safe=safe_module_name)

    return module
Esempio n. 5
0
def _get_paths_from_buildout_script(evaluator, buildout_script_path):
    try:
        module_node = evaluator.parse(
            path=buildout_script_path,
            cache=True,
            cache_path=settings.cache_directory
        )
    except IOError:
        debug.warning('Error trying to read buildout_script: %s', buildout_script_path)
        return

    from jedi.evaluate.context import ModuleContext
    module = ModuleContext(
        evaluator, module_node, buildout_script_path,
        code_lines=get_cached_code_lines(evaluator.grammar, buildout_script_path),
    )
    for path in check_sys_path_modifications(module):
        yield path
Esempio n. 6
0
def _get_paths_from_buildout_script(evaluator, buildout_script_path):
    try:
        module_node = evaluator.parse(
            path=buildout_script_path,
            cache=True,
            cache_path=settings.cache_directory
        )
    except IOError:
        debug.warning('Error trying to read buildout_script: %s', buildout_script_path)
        return

    from jedi.evaluate.context import ModuleContext
    module = ModuleContext(
        evaluator, module_node, buildout_script_path,
        code_lines=get_cached_code_lines(evaluator.grammar, buildout_script_path),
    )
    for path in check_sys_path_modifications(module):
        yield path
Esempio n. 7
0
def create_stub_module(evaluator, actual_context_set, stub_module_node, path,
                       import_names):
    if import_names == ('typing', ):
        module_cls = TypingModuleWrapper
    else:
        module_cls = StubModuleContext
    file_name = os.path.basename(path)
    stub_module_context = module_cls(
        actual_context_set,
        evaluator,
        stub_module_node,
        path=path,
        string_names=import_names,
        # The code was loaded with latest_grammar, so use
        # that.
        code_lines=get_cached_code_lines(evaluator.latest_grammar, path),
        is_package=file_name == '__init__.pyi',
    )
    return stub_module_context
Esempio n. 8
0
def _get_paths_from_buildout_script(inference_state, buildout_script_path):
    file_io = FileIO(str(buildout_script_path))
    try:
        module_node = inference_state.parse(
            file_io=file_io, cache=True, cache_path=settings.cache_directory)
    except IOError:
        debug.warning('Error trying to read buildout_script: %s',
                      buildout_script_path)
        return

    from jedi.inference.value import ModuleValue
    module_context = ModuleValue(
        inference_state,
        module_node,
        file_io=file_io,
        string_names=None,
        code_lines=get_cached_code_lines(inference_state.grammar,
                                         str(buildout_script_path)),
    ).as_context()
    yield from check_sys_path_modifications(module_context)
Esempio n. 9
0
def _load_python_module(evaluator, file_io, sys_path=None,
                        import_names=None, is_package=False):
    try:
        return evaluator.module_cache.get_from_path(file_io.path)
    except KeyError:
        pass

    module_node = evaluator.parse(
        file_io=file_io,
        cache=True,
        diff_cache=settings.fast_parser,
        cache_path=settings.cache_directory
    )

    from jedi.evaluate.context import ModuleContext
    return ModuleContext(
        evaluator, module_node,
        file_io=file_io,
        string_names=import_names,
        code_lines=get_cached_code_lines(evaluator.grammar, file_io.path),
        is_package=is_package,
    )
Esempio n. 10
0
def _find_syntax_node_name(evaluator, access_handle):
    # TODO accessing this is bad, but it probably doesn't matter that much,
    # because we're working with interpreteters only here.
    python_object = access_handle.access._obj
    try:
        python_object = _get_object_to_check(python_object)
        path = inspect.getsourcefile(python_object)
    except TypeError:
        # The type might not be known (e.g. class_with_dict.__weakref__)
        return None
    if path is None or not os.path.exists(path):
        # The path might not exist or be e.g. <stdin>.
        return None

    module_node = _load_module(evaluator, path)

    if inspect.ismodule(python_object):
        # We don't need to check names for modules, because there's not really
        # a way to write a module in a module in Python (and also __name__ can
        # be something like ``email.utils``).
        code_lines = get_cached_code_lines(evaluator.grammar, path)
        return module_node, module_node, path, code_lines

    try:
        name_str = python_object.__name__
    except AttributeError:
        # Stuff like python_function.__code__.
        return None

    if name_str == '<lambda>':
        return None  # It's too hard to find lambdas.

    # Doesn't always work (e.g. os.stat_result)
    names = module_node.get_used_names().get(name_str, [])
    names = [n for n in names if n.is_definition()]
    if not names:
        return None

    try:
        code = python_object.__code__
        # By using the line number of a code object we make the lookup in a
        # file pretty easy. There's still a possibility of people defining
        # stuff like ``a = 3; foo(a); a = 4`` on the same line, but if people
        # do so we just don't care.
        line_nr = code.co_firstlineno
    except AttributeError:
        pass
    else:
        line_names = [name for name in names if name.start_pos[0] == line_nr]
        # There's a chance that the object is not available anymore, because
        # the code has changed in the background.
        if line_names:
            names = line_names

    code_lines = get_cached_code_lines(evaluator.grammar, path)
    # It's really hard to actually get the right definition, here as a last
    # resort we just return the last one. This chance might lead to odd
    # completions at some points but will lead to mostly correct type
    # inference, because people tend to define a public name in a module only
    # once.
    return module_node, names[-1].parent, path, code_lines
Esempio n. 11
0
def _find_syntax_node_name(inference_state, python_object):
    original_object = python_object
    try:
        python_object = _get_object_to_check(python_object)
        path = inspect.getsourcefile(python_object)
    except TypeError:
        # The type might not be known (e.g. class_with_dict.__weakref__)
        return None
    if path is None or not os.path.exists(path):
        # The path might not exist or be e.g. <stdin>.
        return None

    file_io = FileIO(path)
    module_node = _load_module(inference_state, path)

    if inspect.ismodule(python_object):
        # We don't need to check names for modules, because there's not really
        # a way to write a module in a module in Python (and also __name__ can
        # be something like ``email.utils``).
        code_lines = get_cached_code_lines(inference_state.grammar, path)
        return module_node, module_node, file_io, code_lines

    try:
        name_str = python_object.__name__
    except AttributeError:
        # Stuff like python_function.__code__.
        return None

    if name_str == '<lambda>':
        return None  # It's too hard to find lambdas.

    # Doesn't always work (e.g. os.stat_result)
    names = module_node.get_used_names().get(name_str, [])
    # Only functions and classes are relevant. If a name e.g. points to an
    # import, it's probably a builtin (like collections.deque) and needs to be
    # ignored.
    names = [
        n for n in names
        if n.parent.type in ('funcdef', 'classdef') and n.parent.name == n
    ]
    if not names:
        return None

    try:
        code = python_object.__code__
        # By using the line number of a code object we make the lookup in a
        # file pretty easy. There's still a possibility of people defining
        # stuff like ``a = 3; foo(a); a = 4`` on the same line, but if people
        # do so we just don't care.
        line_nr = code.co_firstlineno
    except AttributeError:
        pass
    else:
        line_names = [name for name in names if name.start_pos[0] == line_nr]
        # There's a chance that the object is not available anymore, because
        # the code has changed in the background.
        if line_names:
            names = line_names

    code_lines = get_cached_code_lines(inference_state.grammar, path)
    # It's really hard to actually get the right definition, here as a last
    # resort we just return the last one. This chance might lead to odd
    # completions at some points but will lead to mostly correct type
    # inference, because people tend to define a public name in a module only
    # once.
    tree_node = names[-1].parent
    if tree_node.type == 'funcdef' and get_api_type(
            original_object) == 'instance':
        # If an instance is given and we're landing on a function (e.g.
        # partial in 3.5), something is completely wrong and we should not
        # return that.
        return None
    return module_node, tree_node, file_io, code_lines