From 8658ac5c28ec55e559ca78419985cae7b84f8309 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Mon, 9 Oct 2017 20:28:39 +0200 Subject: [PATCH] Using additional_dynamic_modules sometimes led to weird behavior of using modules twice. --- jedi/evaluate/imports.py | 25 ++++++++++++++----------- jedi/evaluate/sys_path.py | 1 - jedi/evaluate/usages.py | 36 +++++++++++++++++++----------------- 3 files changed, 33 insertions(+), 29 deletions(-) diff --git a/jedi/evaluate/imports.py b/jedi/evaluate/imports.py index a985fde0..ecf656b1 100644 --- a/jedi/evaluate/imports.py +++ b/jedi/evaluate/imports.py @@ -508,6 +508,16 @@ def get_modules_containing_name(evaluator, modules, name): Search a name in the directories of modules. """ from jedi.evaluate.context import ModuleContext + def check_directories(paths): + for p in paths: + if p is not None: + # We need abspath, because the seetings paths might not already + # have been converted to absolute paths. + d = os.path.dirname(os.path.abspath(p)) + for file_name in os.listdir(d): + path = os.path.join(d, file_name) + if file_name.endswith('.py'): + yield path def check_python_file(path): try: @@ -547,17 +557,10 @@ def get_modules_containing_name(evaluator, modules, name): if not settings.dynamic_params_for_other_modules: return - paths = set(settings.additional_dynamic_modules) - for p in used_mod_paths: - if p is not None: - # We need abspath, because the seetings paths might not already - # have been converted to absolute paths. - d = os.path.dirname(os.path.abspath(p)) - for file_name in os.listdir(d): - path = os.path.join(d, file_name) - if path not in used_mod_paths and path not in paths: - if file_name.endswith('.py'): - paths.add(path) + additional = set(os.path.abspath(p) for p in settings.additional_dynamic_modules) + # Check the directories of used modules. + paths = (additional | set(check_directories(used_mod_paths))) \ + - used_mod_paths # Sort here to make issues less random. for p in sorted(paths): diff --git a/jedi/evaluate/sys_path.py b/jedi/evaluate/sys_path.py index d3a65638..82e5e9df 100644 --- a/jedi/evaluate/sys_path.py +++ b/jedi/evaluate/sys_path.py @@ -80,7 +80,6 @@ def _abs_path(module_context, path): return None base_dir = os.path.dirname(module_path) - print(base_dir, path) return os.path.abspath(os.path.join(base_dir, path)) diff --git a/jedi/evaluate/usages.py b/jedi/evaluate/usages.py index 75ff1e5d..0315278e 100644 --- a/jedi/evaluate/usages.py +++ b/jedi/evaluate/usages.py @@ -3,32 +3,33 @@ from jedi.evaluate.filters import TreeNameDefinition from jedi.evaluate.context import ModuleContext +def _resolve_names(definition_names, avoid_names=()): + for name in definition_names: + if name in avoid_names: + # Avoiding recursions here, because goto on a module name lands + # on the same module. + continue + + if not isinstance(name, imports.SubModuleName): + # SubModuleNames are not actually existing names but created + # names when importing something like `import foo.bar.baz`. + yield name + + if name.api_type == 'module': + for name in _resolve_names(name.goto(), definition_names): + yield name + + def usages(evaluator, module_context, tree_name): """ :param definitions: list of Name """ - def resolve_names(definition_names, avoid_names=()): - for name in definition_names: - if name in avoid_names: - # Avoiding recursions here, because goto on a module name lands - # on the same module. - continue - - if not isinstance(name, imports.SubModuleName): - # SubModuleNames are not actually existing names but created - # names when importing something like `import foo.bar.baz`. - yield name - - if name.api_type == 'module': - for name in resolve_names(name.goto(), definition_names): - yield name - def find_names(module_context, tree_name): context = evaluator.create_context(module_context, tree_name) name = TreeNameDefinition(context, tree_name) found_names = set(name.goto()) found_names.add(name) - return dcti(resolve_names(found_names)) + return dcti(_resolve_names(found_names)) def dcti(names): return dict( @@ -40,6 +41,7 @@ def usages(evaluator, module_context, tree_name): found_names = find_names(module_context, tree_name) modules = set(d.get_root_context() for d in found_names.values()) modules = set(m for m in modules if isinstance(m, ModuleContext)) + for m in imports.get_modules_containing_name(evaluator, modules, search_name): for name_leaf in m.tree_node.get_used_names().get(search_name, []): new = find_names(m, name_leaf)