Better signature calculation

This commit is contained in:
Dave Halter
2019-05-23 01:36:51 +02:00
parent b2b08ab432
commit 9aa8f6bcf2
4 changed files with 74 additions and 35 deletions
+44 -11
View File
@@ -1,3 +1,6 @@
from jedi._compatibility import Parameter
class AbstractSignature(object):
def __init__(self, context, is_bound=False):
self.context = context
@@ -8,15 +11,33 @@ class AbstractSignature(object):
return self.context.name
@property
def annotation(self):
return None
def annotation_string(self):
return ''
def to_string(self):
param_code = ', '.join(n.to_string() for n in self.get_param_names())
s = self.name.string_name + '(' + param_code + ')'
annotation = self.annotation
if annotation is not None:
s += ' -> ' + annotation.get_code(include_prefix=False)
def param_strings():
is_positional = False
is_kw_only = False
for n in self.get_param_names():
kind = n.get_kind()
is_positional |= kind == Parameter.POSITIONAL_ONLY
if is_positional and kind != Parameter.POSITIONAL_ONLY:
yield '/'
is_positional = False
if kind == Parameter.KEYWORD_ONLY and not is_kw_only:
yield '*'
is_kw_only = True
yield n.to_string()
if is_positional:
yield '/'
s = self.name.string_name + '(' + ', '.join(param_strings()) + ')'
annotation = self.annotation_string
if annotation:
s += ' -> ' + annotation
return s
def bind(self, context):
@@ -38,21 +59,33 @@ class TreeSignature(AbstractSignature):
return TreeSignature(context, self._function_context, is_bound=True)
@property
def annotation(self):
def _annotation(self):
# Classes don't need annotations, even if __init__ has one. They always
# return themselves.
if self.context.is_class():
return None
return self._function_context.tree_node.annotation
@property
def annotation_string(self):
a = self._annotation
if a is None:
return ''
return a.get_code(include_prefix=False)
class BuiltinSignature(AbstractSignature):
def __init__(self, context, return_string, is_bound=False):
super(BuiltinSignature, self).__init__(context, is_bound)
self._return_string = return_string
@property
def annotation_string(self):
return self._return_string
@property
def _function_context(self):
return self.context
def to_string(self):
return self.name.string_name + self.context.get_signature_text()
def bind(self, context):
raise NotImplementedError('pls implement, need test case, %s' % context)