mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-06 14:04:26 +08:00
Fix string name completion for stuff like dirname and abspath
This commit is contained in:
@@ -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):
|
||||
# First we want to find out what can actually be changed as a name.
|
||||
base_name = os.path.basename(string)
|
||||
like_name_length = len(base_name + like_name)
|
||||
like_name_length = len(os.path.basename(string) + like_name)
|
||||
|
||||
string = _get_string_additions(module_context, start_leaf) + string
|
||||
# Here we use basename again, because if strings are added like
|
||||
|
||||
@@ -386,7 +386,7 @@ def get_global_filters(evaluator, context, until_position, origin_scope):
|
||||
>>> list(filters[1].values()) # package modules -> Also empty.
|
||||
[]
|
||||
>>> 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
|
||||
true (default).
|
||||
|
||||
@@ -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.
|
||||
"""
|
||||
import parso
|
||||
import os
|
||||
|
||||
from jedi._compatibility import force_unicode, Parameter
|
||||
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 = {
|
||||
'builtins': {
|
||||
'getattr': builtins_getattr,
|
||||
@@ -729,6 +746,11 @@ _implemented = {
|
||||
# For now this works at least better than Jedi trying to understand it.
|
||||
'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),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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())
|
||||
|
||||
|
||||
f1 = join(root_dir, 'example.py')
|
||||
f2 = join(root_dir, 'test', 'example.py')
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'file, code, column, expected', [
|
||||
# General tests / relative paths
|
||||
@@ -199,6 +203,12 @@ def test_keyword_completion(Script, code, has_keywords):
|
||||
# Python 2.
|
||||
('example.py', 'x = f(b"t" + "est")', 17, [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):
|
||||
|
||||
Reference in New Issue
Block a user