diff --git a/jedi/evaluate/compiled/access.py b/jedi/evaluate/compiled/access.py index 4e704947..20e9df30 100644 --- a/jedi/evaluate/compiled/access.py +++ b/jedi/evaluate/compiled/access.py @@ -377,6 +377,21 @@ class DirectObjectAccess(object): return inspect.isclass(self._obj) and self._obj != type def get_signature_params(self): + return [ + SignatureParam( + name=p.name, + has_default=p.default is not p.empty, + default=self._create_access_path(p.default), + has_annotation=p.annotation is not p.empty, + annotation=self._create_access_path(p.annotation), + kind_name=str(p.kind) + ) for p in self._get_signature().parameters.values() + ] + + def get_signature_text(self): + return str(self._get_signature()) + + def _get_signature(self): obj = self._obj if py_version < 33: raise ValueError("inspect.signature was introduced in 3.3") @@ -397,22 +412,12 @@ class DirectObjectAccess(object): raise ValueError try: - signature = inspect.signature(obj) + return inspect.signature(obj) except (RuntimeError, TypeError): # Reading the code of the function in Python 3.6 implies there are # at least these errors that might occur if something is wrong with # the signature. In that case we just want a simple escape for now. raise ValueError - return [ - SignatureParam( - name=p.name, - has_default=p.default is not p.empty, - default=self._create_access_path(p.default), - has_annotation=p.annotation is not p.empty, - annotation=self._create_access_path(p.annotation), - kind_name=str(p.kind) - ) for p in signature.parameters.values() - ] def negate(self): return self._create_access_path(-self._obj) diff --git a/jedi/evaluate/compiled/context.py b/jedi/evaluate/compiled/context.py index 36f1936b..2f664b84 100644 --- a/jedi/evaluate/compiled/context.py +++ b/jedi/evaluate/compiled/context.py @@ -5,6 +5,7 @@ import re from functools import partial from jedi import debug +from jedi.evaluate.utils import to_list from jedi._compatibility import force_unicode, Parameter, cast_path from jedi.cache import underscore_memoization, memoize_method from jedi.evaluate.filters import AbstractFilter @@ -111,6 +112,7 @@ class CompiledObject(Context): def py__doc__(self): return self.access_handle.py__doc__() + @to_list def get_param_names(self): try: signature_params = self.access_handle.get_signature_params() @@ -126,6 +128,13 @@ class CompiledObject(Context): for signature_param in signature_params: yield SignatureParamName(self, signature_param) + def get_signature_text(self): + try: + return self.access_handle.get_signature_text() + except ValueError: + params_str, ret = self._parse_function_doc() + return '(' + params_str + ')' + ret + def get_signatures(self): return [BuiltinSignature(self)] diff --git a/jedi/evaluate/signature.py b/jedi/evaluate/signature.py index 9b3fc2df..d5e1d9db 100644 --- a/jedi/evaluate/signature.py +++ b/jedi/evaluate/signature.py @@ -10,6 +10,7 @@ class AbstractSignature(object): def name(self): return self.context.name + @property def annotation(self): return None @@ -34,6 +35,7 @@ class TreeSignature(AbstractSignature): def bind(self, context): return TreeSignature(context, self._function_context, is_bound=True) + @property def annotation(self): return self._function_context.tree_node.annotation @@ -52,7 +54,7 @@ class BuiltinSignature(AbstractSignature): return self.context def to_string(self): - return '' + return self.name.string_name + self.context.get_signature_text() def bind(self, context): raise NotImplementedError('pls implement, need test case, %s' % context) diff --git a/test/test_evaluate/test_signature.py b/test/test_evaluate/test_signature.py new file mode 100644 index 00000000..7f744247 --- /dev/null +++ b/test/test_evaluate/test_signature.py @@ -0,0 +1,15 @@ +import pytest + +from jedi.evaluate.gradual.conversion import stub_to_actual_context_set + + +def test_compiled_signature(Script): + code = 'import math; math.cos' + sig = 'cos(x, /)' + d, = Script(code).goto_definitions() + context, = d._name.infer() + compiled, = stub_to_actual_context_set(context) + signature, = compiled.get_signatures() + assert signature.to_string() == sig + assert signature.get_param_names() == [] + assert signature.annotation is None