Fix string name completion for stuff like dirname and abspath

This commit is contained in:
Dave Halter
2019-08-06 19:38:16 +02:00
parent 3a9dc0ca2e
commit 99008eef43
4 changed files with 34 additions and 3 deletions

View File

@@ -8,8 +8,7 @@ from jedi.evaluate.helpers import get_str_or_none
def file_name_completions(evaluator, module_context, start_leaf, string, like_name): def file_name_completions(evaluator, module_context, start_leaf, string, like_name):
# First we want to find out what can actually be changed as a name. # First we want to find out what can actually be changed as a name.
base_name = os.path.basename(string) like_name_length = len(os.path.basename(string) + like_name)
like_name_length = len(base_name + like_name)
string = _get_string_additions(module_context, start_leaf) + string string = _get_string_additions(module_context, start_leaf) + string
# Here we use basename again, because if strings are added like # Here we use basename again, because if strings are added like

View File

@@ -386,7 +386,7 @@ def get_global_filters(evaluator, context, until_position, origin_scope):
>>> list(filters[1].values()) # package modules -> Also empty. >>> list(filters[1].values()) # package modules -> Also empty.
[] []
>>> sorted(name.string_name for name in filters[2].values()) # Module attributes >>> sorted(name.string_name for name in filters[2].values()) # Module attributes
['__doc__', '__file__', '__name__', '__package__'] ['__doc__', '__name__', '__package__']
Finally, it yields the builtin filter, if `include_builtin` is Finally, it yields the builtin filter, if `include_builtin` is
true (default). true (default).

View File

@@ -10,6 +10,7 @@ the standard library. The usual way to understand the standard library is the
compiled module that returns the types for C-builtins. compiled module that returns the types for C-builtins.
""" """
import parso import parso
import os
from jedi._compatibility import force_unicode, Parameter from jedi._compatibility import force_unicode, Parameter
from jedi import debug from jedi import debug
@@ -678,6 +679,22 @@ def _operator_itemgetter(args_context_set, obj, arguments):
]) ])
def _create_string_input_function(func):
@argument_clinic('string, /', want_obj=True, want_arguments=True)
def wrapper(strings, obj, arguments):
def iterate():
for context in strings:
s = get_str_or_none(context)
if s is not None:
s = func(s)
yield compiled.create_simple_object(context.evaluator, s)
contexts = ContextSet(iterate())
if contexts:
return contexts
return obj.py__call__(arguments)
return wrapper
_implemented = { _implemented = {
'builtins': { 'builtins': {
'getattr': builtins_getattr, 'getattr': builtins_getattr,
@@ -729,6 +746,11 @@ _implemented = {
# For now this works at least better than Jedi trying to understand it. # For now this works at least better than Jedi trying to understand it.
'dataclass': _dataclass 'dataclass': _dataclass
}, },
'os.path': {
'dirname': _create_string_input_function(os.path.dirname),
'abspath': _create_string_input_function(os.path.abspath),
'relpath': _create_string_input_function(os.path.relpath),
}
} }

View File

@@ -159,6 +159,10 @@ def test_keyword_completion(Script, code, has_keywords):
assert has_keywords == any(x.is_keyword for x in Script(code).completions()) assert has_keywords == any(x.is_keyword for x in Script(code).completions())
f1 = join(root_dir, 'example.py')
f2 = join(root_dir, 'test', 'example.py')
@pytest.mark.parametrize( @pytest.mark.parametrize(
'file, code, column, expected', [ 'file, code, column, expected', [
# General tests / relative paths # General tests / relative paths
@@ -199,6 +203,12 @@ def test_keyword_completion(Script, code, has_keywords):
# Python 2. # Python 2.
('example.py', 'x = f(b"t" + "est")', 17, [s]), ('example.py', 'x = f(b"t" + "est")', 17, [s]),
('example.py', '"test" + "', None, [s]), ('example.py', '"test" + "', None, [s]),
# __file__
(f1, 'from os.path import *\ndirname(__file__) + "%stest' % s, None, [s]),
(f2, 'from os.path import *\ndirname(__file__) + "%stest_ca' % s, None, ['che.py']),
(f2, 'from os.path import *\ndirname(abspath(__file__)) + "%stest_ca' % s,
None, ['che.py']),
] ]
) )
def test_file_path_completions(Script, file, code, column, expected): def test_file_path_completions(Script, file, code, column, expected):