diff --git a/jedi/api/file_name.py b/jedi/api/file_name.py index fac187f6..5c2ce3ef 100644 --- a/jedi/api/file_name.py +++ b/jedi/api/file_name.py @@ -57,16 +57,14 @@ def _get_string_additions(module_context, start_leaf): addition = start_leaf.get_previous_leaf() if addition != '+': return '' - return _add_strings(module_context, reversed(list(iterate_nodes()))) + context = module_context.create_context(start_leaf) + return _add_strings(context, reversed(list(iterate_nodes()))) -def _add_strings(module_context, nodes, add_slash=False): +def _add_strings(context, nodes, add_slash=False): string = '' - context = None first = True for child_node in nodes: - if context is None: - context = module_context.create_context(child_node) contexts = context.eval_node(child_node) if len(contexts) != 1: return None @@ -87,18 +85,42 @@ class FileName(AbstractArbitraryName): def _maybe_add_os_path_join(module_context, start_leaf, string): + def check_for_power(join_atom, nodes): + context = module_context.create_context(join_atom) + contexts = context.eval_node(join_atom) + if any([c.name.get_qualified_names(include_module_names=True) + != ('os', 'path', 'join') for c in contexts]): + return string, False + return _add_strings(context, nodes, add_slash=True), True + arglist = start_leaf.parent - if arglist.type == 'arglist': + if start_leaf.type == 'error_leaf': + index = arglist.children.index(start_leaf) + if index > 0: + error_node = arglist.children[index - 1] + if error_node.type == 'error_node' and len(error_node.children) >= 3: + atom = error_node.children[-3] + arglist = error_node.children[-1] + if atom.type in ('atom_expr', 'power', 'name') and arglist.type == 'arglist': + return check_for_power(atom, arglist.children[::2]) + elif arglist.type == 'arglist': trailer = arglist.parent - if trailer.type == 'trailer': + if trailer.type == 'error_node': + index = trailer.children.index(arglist) + assert index >= 2 + assert trailer.children[index - 1] == '(' + name = trailer.children[index - 2] + if name.type in ('atom_expr', 'power', 'name'): + nodes = arglist.children[:arglist.children.index(start_leaf):2] + return check_for_power(name, nodes) + + elif False: + for node in reversed(trailer.children[:trailer.children.index(arglist)]): + print(node) + elif trailer.type == 'trailer': atom = trailer.get_previous_sibling() if atom.type != 'trailer': - context = module_context.create_context(atom) - contexts = context.eval_node(atom) - if any([c.name.get_qualified_names(include_module_names=True) - != ('os', 'path', 'join') for c in contexts]): - return string, False nodes = arglist.children[:arglist.children.index(start_leaf):2] - return _add_strings(module_context, nodes, add_slash=True), True + return check_for_power(atom, nodes) return string, False diff --git a/test/test_api/test_completion.py b/test/test_api/test_completion.py index 0ff73dc2..9cc155ae 100644 --- a/test/test_api/test_completion.py +++ b/test/test_api/test_completion.py @@ -213,9 +213,15 @@ os_path = 'from os.path import *\n' (f2, os_path + 'join(dirname(__file__), "completion", "basi', None, ['c.py']), (f2, os_path + 'join(dirname(__file__), "completion", "basi)', 43, ['c.py']), (f2, os_path + 'join(dirname(__file__), "completion", "basi")', 43, ['c.py']), - (f2, os_path + 'join(dirname(__file__), "completion", "basi)', 35, []), + (f2, os_path + 'join(dirname(__file__), "completion", "basi)', 35, ['']), (f2, os_path + 'join(dirname(__file__), "completion", "basi)', 33, ['on']), (f2, os_path + 'join(dirname(__file__), "completion", "basi")', 33, ['on']), + + # join with one argument + #(f2, os_path + 'join("tes', 10, ['t']), + #(f2, os_path + 'join("tes)', 10, ['t']), + #(f2, os_path + 'join("tes"', 10, ['t']), + #(f2, os_path + 'join("tes")', 10, ['t']), ] ) def test_file_path_completions(Script, file, code, column, expected):