You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			153 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Python
		
	
			
		
		
	
	
			153 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Python
		
	
from inspect import Parameter
 | 
						|
 | 
						|
from jedi.cache import memoize_method
 | 
						|
from jedi import debug
 | 
						|
from jedi import parser_utils
 | 
						|
 | 
						|
 | 
						|
class _SignatureMixin:
 | 
						|
    def to_string(self):
 | 
						|
        def param_strings():
 | 
						|
            is_positional = False
 | 
						|
            is_kw_only = False
 | 
						|
            for n in self.get_param_names(resolve_stars=True):
 | 
						|
                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.VAR_POSITIONAL:
 | 
						|
                    is_kw_only = True
 | 
						|
                elif 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
 | 
						|
 | 
						|
 | 
						|
class AbstractSignature(_SignatureMixin):
 | 
						|
    def __init__(self, value, is_bound=False):
 | 
						|
        self.value = value
 | 
						|
        self.is_bound = is_bound
 | 
						|
 | 
						|
    @property
 | 
						|
    def name(self):
 | 
						|
        return self.value.name
 | 
						|
 | 
						|
    @property
 | 
						|
    def annotation_string(self):
 | 
						|
        return ''
 | 
						|
 | 
						|
    def get_param_names(self, resolve_stars=False):
 | 
						|
        param_names = self._function_value.get_param_names()
 | 
						|
        if self.is_bound:
 | 
						|
            return param_names[1:]
 | 
						|
        return param_names
 | 
						|
 | 
						|
    def bind(self, value):
 | 
						|
        raise NotImplementedError
 | 
						|
 | 
						|
    def matches_signature(self, arguments):
 | 
						|
        return True
 | 
						|
 | 
						|
    def __repr__(self):
 | 
						|
        if self.value is self._function_value:
 | 
						|
            return '<%s: %s>' % (self.__class__.__name__, self.value)
 | 
						|
        return '<%s: %s, %s>' % (self.__class__.__name__, self.value, self._function_value)
 | 
						|
 | 
						|
 | 
						|
class TreeSignature(AbstractSignature):
 | 
						|
    def __init__(self, value, function_value=None, is_bound=False):
 | 
						|
        super().__init__(value, is_bound)
 | 
						|
        self._function_value = function_value or value
 | 
						|
 | 
						|
    def bind(self, value):
 | 
						|
        return TreeSignature(value, self._function_value, is_bound=True)
 | 
						|
 | 
						|
    @property
 | 
						|
    def _annotation(self):
 | 
						|
        # Classes don't need annotations, even if __init__ has one. They always
 | 
						|
        # return themselves.
 | 
						|
        if self.value.is_class():
 | 
						|
            return None
 | 
						|
        return self._function_value.tree_node.annotation
 | 
						|
 | 
						|
    @property
 | 
						|
    def annotation_string(self):
 | 
						|
        a = self._annotation
 | 
						|
        if a is None:
 | 
						|
            return ''
 | 
						|
        return a.get_code(include_prefix=False)
 | 
						|
 | 
						|
    @memoize_method
 | 
						|
    def get_param_names(self, resolve_stars=False):
 | 
						|
        params = self._function_value.get_param_names()
 | 
						|
        if resolve_stars:
 | 
						|
            from jedi.inference.star_args import process_params
 | 
						|
            params = process_params(params)
 | 
						|
        if self.is_bound:
 | 
						|
            return params[1:]
 | 
						|
        return params
 | 
						|
 | 
						|
    def matches_signature(self, arguments):
 | 
						|
        from jedi.inference.param import get_executed_param_names_and_issues
 | 
						|
        executed_param_names, issues = \
 | 
						|
            get_executed_param_names_and_issues(self._function_value, arguments)
 | 
						|
        if issues:
 | 
						|
            return False
 | 
						|
 | 
						|
        matches = all(executed_param_name.matches_signature()
 | 
						|
                      for executed_param_name in executed_param_names)
 | 
						|
        if debug.enable_notice:
 | 
						|
            tree_node = self._function_value.tree_node
 | 
						|
            signature = parser_utils.get_signature(tree_node)
 | 
						|
            if matches:
 | 
						|
                debug.dbg("Overloading match: %s@%s (%s)",
 | 
						|
                          signature, tree_node.start_pos[0], arguments, color='BLUE')
 | 
						|
            else:
 | 
						|
                debug.dbg("Overloading no match: %s@%s (%s)",
 | 
						|
                          signature, tree_node.start_pos[0], arguments, color='BLUE')
 | 
						|
        return matches
 | 
						|
 | 
						|
 | 
						|
class BuiltinSignature(AbstractSignature):
 | 
						|
    def __init__(self, value, return_string, function_value=None, is_bound=False):
 | 
						|
        super().__init__(value, is_bound)
 | 
						|
        self._return_string = return_string
 | 
						|
        self.__function_value = function_value
 | 
						|
 | 
						|
    @property
 | 
						|
    def annotation_string(self):
 | 
						|
        return self._return_string
 | 
						|
 | 
						|
    @property
 | 
						|
    def _function_value(self):
 | 
						|
        if self.__function_value is None:
 | 
						|
            return self.value
 | 
						|
        return self.__function_value
 | 
						|
 | 
						|
    def bind(self, value):
 | 
						|
        return BuiltinSignature(
 | 
						|
            value, self._return_string,
 | 
						|
            function_value=self.value,
 | 
						|
            is_bound=True
 | 
						|
        )
 | 
						|
 | 
						|
 | 
						|
class SignatureWrapper(_SignatureMixin):
 | 
						|
    def __init__(self, wrapped_signature):
 | 
						|
        self._wrapped_signature = wrapped_signature
 | 
						|
 | 
						|
    def __getattr__(self, name):
 | 
						|
        return getattr(self._wrapped_signature, name)
 |