mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-09 23:34:45 +08:00
Start using inspect.signature for CompiledObject params.
Fixes 917 and 924.
This commit is contained in:
@@ -115,13 +115,19 @@ class CompiledObject(Context):
|
|||||||
return inspect.getdoc(self.obj) or ''
|
return inspect.getdoc(self.obj) or ''
|
||||||
|
|
||||||
def get_param_names(self):
|
def get_param_names(self):
|
||||||
params_str, ret = self._parse_function_doc()
|
try:
|
||||||
tokens = params_str.split(',')
|
signature = inspect.signature(self.obj)
|
||||||
if inspect.ismethoddescriptor(self.obj):
|
except ValueError: # Has no signature
|
||||||
tokens.insert(0, 'self')
|
params_str, ret = self._parse_function_doc()
|
||||||
for p in tokens:
|
tokens = params_str.split(',')
|
||||||
parts = p.strip().split('=')
|
if inspect.ismethoddescriptor(self.obj):
|
||||||
yield UnresolvableParamName(self, parts[0])
|
tokens.insert(0, 'self')
|
||||||
|
for p in tokens:
|
||||||
|
parts = p.strip().split('=')
|
||||||
|
yield UnresolvableParamName(self, parts[0])
|
||||||
|
else:
|
||||||
|
for signature_param in signature.parameters.values():
|
||||||
|
yield SignatureParamName(self, signature_param)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '<%s: %s>' % (self.__class__.__name__, repr(self.obj))
|
return '<%s: %s>' % (self.__class__.__name__, repr(self.obj))
|
||||||
@@ -276,6 +282,29 @@ class CompiledName(AbstractNameDefinition):
|
|||||||
return [_create_from_name(self._evaluator, module, self.parent_context, self.string_name)]
|
return [_create_from_name(self._evaluator, module, self.parent_context, self.string_name)]
|
||||||
|
|
||||||
|
|
||||||
|
class SignatureParamName(AbstractNameDefinition):
|
||||||
|
api_type = 'param'
|
||||||
|
|
||||||
|
def __init__(self, compiled_obj, signature_param):
|
||||||
|
self.parent_context = compiled_obj.parent_context
|
||||||
|
self._signature_param = signature_param
|
||||||
|
|
||||||
|
@property
|
||||||
|
def string_name(self):
|
||||||
|
return self._signature_param.name
|
||||||
|
|
||||||
|
def infer(self):
|
||||||
|
p = self._signature_param
|
||||||
|
evaluator = self.parent_context.evaluator
|
||||||
|
types = set()
|
||||||
|
if p.default is not p.empty:
|
||||||
|
types.add(create(evaluator, p.default))
|
||||||
|
if p.annotation is not p.empty:
|
||||||
|
annotation = create(evaluator, p.annotation)
|
||||||
|
types |= annotation.execute_evaluated()
|
||||||
|
return types
|
||||||
|
|
||||||
|
|
||||||
class UnresolvableParamName(AbstractNameDefinition):
|
class UnresolvableParamName(AbstractNameDefinition):
|
||||||
api_type = 'param'
|
api_type = 'param'
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
"""
|
"""
|
||||||
Tests of ``jedi.api.Interpreter``.
|
Tests of ``jedi.api.Interpreter``.
|
||||||
"""
|
"""
|
||||||
|
import pytest
|
||||||
|
|
||||||
import jedi
|
import jedi
|
||||||
from jedi._compatibility import is_py33
|
from jedi._compatibility import is_py33, exec_function, py_version
|
||||||
from jedi.evaluate.compiled import mixed
|
from jedi.evaluate.compiled import mixed
|
||||||
|
|
||||||
|
|
||||||
@@ -225,3 +226,29 @@ def test_endless_yield():
|
|||||||
# If iterating over lists it should not be possible to take an extremely
|
# If iterating over lists it should not be possible to take an extremely
|
||||||
# long time.
|
# long time.
|
||||||
_assert_interpreter_complete('list(lst)[9000].rea', locals(), ['real'])
|
_assert_interpreter_complete('list(lst)[9000].rea', locals(), ['real'])
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skipif('py_version < 33', reason='inspect.signature was created in 3.3.')
|
||||||
|
def test_completion_params():
|
||||||
|
foo = lambda a, b=3: None
|
||||||
|
|
||||||
|
script = jedi.Interpreter('foo', [locals()])
|
||||||
|
c, = script.completions()
|
||||||
|
assert [p.name for p in c.params] == ['a', 'b']
|
||||||
|
assert c.params[0]._goto_definitions() == []
|
||||||
|
t, = c.params[1]._goto_definitions()
|
||||||
|
assert t.name == 'int'
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skipif('py_version < 33', reason='inspect.signature was created in 3.3.')
|
||||||
|
def test_completion_param_annotations():
|
||||||
|
# Need to define this function not directly in Python. Otherwise Jedi is to
|
||||||
|
# clever and uses the Python code instead of the signature object.
|
||||||
|
code = 'def foo(a: 1, b: str, c: int = 1.0): pass'
|
||||||
|
exec_function(code, locals())
|
||||||
|
script = jedi.Interpreter('foo', [locals()])
|
||||||
|
c, = script.completions()
|
||||||
|
a, b, c = c.params
|
||||||
|
assert a._goto_definitions() == []
|
||||||
|
assert [d.name for d in b._goto_definitions()] == ['str']
|
||||||
|
assert [d.name for d in c._goto_definitions()] == ['int', 'float']
|
||||||
|
|||||||
Reference in New Issue
Block a user