mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-15 18:17:07 +08:00
Fix named param completion and add a few tests.
This commit is contained in:
@@ -14,6 +14,7 @@ from jedi.parser import tree
|
|||||||
from jedi.parser.utils import load_parser
|
from jedi.parser.utils import load_parser
|
||||||
from jedi.cache import memoize_method
|
from jedi.cache import memoize_method
|
||||||
from jedi.evaluate import representation as er
|
from jedi.evaluate import representation as er
|
||||||
|
from jedi.evaluate import instance
|
||||||
from jedi.evaluate import iterable
|
from jedi.evaluate import iterable
|
||||||
from jedi.evaluate import imports
|
from jedi.evaluate import imports
|
||||||
from jedi.evaluate import compiled
|
from jedi.evaluate import compiled
|
||||||
@@ -305,14 +306,14 @@ class BaseDefinition(object):
|
|||||||
"""
|
"""
|
||||||
Follow both statements and imports, as far as possible.
|
Follow both statements and imports, as far as possible.
|
||||||
"""
|
"""
|
||||||
if self._definition.isinstance(tree.ExprStmt):
|
if self._name.api_type == 'expr_stmt':
|
||||||
return self._evaluator.eval_statement(self._definition)
|
return self._evaluator.eval_statement(self._definition)
|
||||||
elif self._definition.isinstance(tree.Import):
|
elif self._name.api_type == 'import':
|
||||||
raise DeprecationWarning
|
raise DeprecationWarning
|
||||||
# TODO self._name.infer()?
|
# TODO self._name.infer()?
|
||||||
return imports.ImportWrapper(self._evaluator, self._name).follow()
|
return imports.ImportWrapper(self._evaluator, self._name).follow()
|
||||||
else:
|
else:
|
||||||
return set([self._definition])
|
return set([self._name.parent_context])
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@memoize_method
|
@memoize_method
|
||||||
@@ -321,33 +322,33 @@ class BaseDefinition(object):
|
|||||||
Raises an ``AttributeError``if the definition is not callable.
|
Raises an ``AttributeError``if the definition is not callable.
|
||||||
Otherwise returns a list of `Definition` that represents the params.
|
Otherwise returns a list of `Definition` that represents the params.
|
||||||
"""
|
"""
|
||||||
|
def get_param_names(context):
|
||||||
|
param_names = []
|
||||||
|
if context.api_type == 'function':
|
||||||
|
param_names = context.get_param_names()
|
||||||
|
if isinstance(context, instance.BoundMethod):
|
||||||
|
param_names = param_names[1:]
|
||||||
|
elif isinstance(context, (instance.AbstractInstanceContext, er.ClassContext)):
|
||||||
|
if isinstance(context, er.ClassContext):
|
||||||
|
search = '__init__'
|
||||||
|
else:
|
||||||
|
search = '__call__'
|
||||||
|
names = context.get_function_slot_names(search)
|
||||||
|
if not names:
|
||||||
|
return []
|
||||||
|
|
||||||
|
# Just take the first one here, not optimal, but currently
|
||||||
|
# there's no better solution.
|
||||||
|
inferred = names[0].infer()
|
||||||
|
return get_param_names(next(iter(inferred)))
|
||||||
|
return param_names
|
||||||
|
|
||||||
followed = list(self._follow_statements_imports())
|
followed = list(self._follow_statements_imports())
|
||||||
if not followed or not hasattr(followed[0], 'py__call__'):
|
if not followed or not hasattr(followed[0], 'py__call__'):
|
||||||
raise AttributeError()
|
raise AttributeError()
|
||||||
followed = followed[0] # only check the first one.
|
context = followed[0] # only check the first one.
|
||||||
|
|
||||||
if followed.type in ('funcdef', 'lambda'):
|
return [_Param(self._evaluator, n) for n in get_param_names(context)]
|
||||||
if isinstance(followed, er.InstanceElement):
|
|
||||||
params = followed.params[1:]
|
|
||||||
else:
|
|
||||||
params = followed.params
|
|
||||||
elif followed.isinstance(er.compiled.CompiledObject):
|
|
||||||
params = followed.params
|
|
||||||
elif isinstance(followed, er.Class):
|
|
||||||
try:
|
|
||||||
sub = followed.get_subscope_by_name('__init__')
|
|
||||||
params = sub.params[1:] # ignore self
|
|
||||||
except KeyError:
|
|
||||||
return []
|
|
||||||
elif isinstance(followed, er.Instance):
|
|
||||||
try:
|
|
||||||
sub = followed.get_subscope_by_name('__call__')
|
|
||||||
params = sub.params[1:] # ignore self
|
|
||||||
except KeyError:
|
|
||||||
return []
|
|
||||||
else:
|
|
||||||
return []
|
|
||||||
return [_Param(self._evaluator, p.name) for p in params]
|
|
||||||
|
|
||||||
def parent(self):
|
def parent(self):
|
||||||
scope = self._definition.get_parent_scope()
|
scope = self._definition.get_parent_scope()
|
||||||
|
|||||||
@@ -22,7 +22,8 @@ def get_call_signature_param_names(call_signatures):
|
|||||||
# Allow access on _definition here, because it's a
|
# Allow access on _definition here, because it's a
|
||||||
# public API and we don't want to make the internal
|
# public API and we don't want to make the internal
|
||||||
# Name object public.
|
# Name object public.
|
||||||
if p._definition.stars == 0: # no *args/**kwargs
|
tree_param = tree.search_ancestor(p._name.tree_name, 'param')
|
||||||
|
if tree_param.stars == 0: # no *args/**kwargs
|
||||||
yield p._name
|
yield p._name
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ my_lambda = lambda lambda_param: lambda_param + 1
|
|||||||
#? 22 ['lambda_param']
|
#? 22 ['lambda_param']
|
||||||
my_lambda(lambda_param)
|
my_lambda(lambda_param)
|
||||||
|
|
||||||
# __call__
|
# __call__ / __init__
|
||||||
class Test(object):
|
class Test(object):
|
||||||
def __init__(self, hello_other):
|
def __init__(self, hello_other):
|
||||||
pass
|
pass
|
||||||
@@ -42,7 +42,21 @@ class Test(object):
|
|||||||
def __call__(self, hello):
|
def __call__(self, hello):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def test(self, blub):
|
||||||
|
pass
|
||||||
|
|
||||||
|
#? 10 ['hello_other']
|
||||||
|
Test(hello=)
|
||||||
#? 12 ['hello']
|
#? 12 ['hello']
|
||||||
Test()(hello=)
|
Test()(hello=)
|
||||||
#? 11 []
|
#? 11 []
|
||||||
Test()(self=)
|
Test()(self=)
|
||||||
|
#? 16 []
|
||||||
|
Test().test(self=)
|
||||||
|
#? 16 ['blub']
|
||||||
|
Test().test(blub=)
|
||||||
|
|
||||||
|
# builtins
|
||||||
|
|
||||||
|
#? 12 []
|
||||||
|
any(iterable=)
|
||||||
|
|||||||
Reference in New Issue
Block a user