diff --git a/jedi/evaluate/base_context.py b/jedi/evaluate/base_context.py index b1fdb9ac..318a5359 100644 --- a/jedi/evaluate/base_context.py +++ b/jedi/evaluate/base_context.py @@ -62,6 +62,9 @@ class HelperContextMixin: return False def is_same_class(self, class2): + # Class matching should prefer comparisons that are not this function. + if type(class2).is_same_class != HelperContextMixin.is_same_class: + return class2.is_same_class(self) return self == class2 diff --git a/jedi/evaluate/context/function.py b/jedi/evaluate/context/function.py index c5afc758..c9722eed 100644 --- a/jedi/evaluate/context/function.py +++ b/jedi/evaluate/context/function.py @@ -292,8 +292,8 @@ class FunctionExecutionContext(TreeContext): if debug.enable_notice: signature = parser_utils.get_call_signature(self.tree_node) if matches: - debug.dbg("Overloading match: %s@%s", - signature, self.tree_node.start_pos[0], color='BLUE') + debug.dbg("Overloading match: %s@%s (%s)", + signature, self.tree_node.start_pos[0], self.var_args, color='BLUE') else: debug.dbg("Overloading no match: %s@%s (%s)", signature, self.tree_node.start_pos[0], self.var_args, color='BLUE') diff --git a/jedi/evaluate/context/iterable.py b/jedi/evaluate/context/iterable.py index 0c4b0137..04dccf87 100644 --- a/jedi/evaluate/context/iterable.py +++ b/jedi/evaluate/context/iterable.py @@ -191,6 +191,11 @@ class ComprehensionMixin(object): return "<%s of %s>" % (type(self).__name__, self._atom) +class _DictMixin(object): + def _get_generics(self): + return tuple(c_set.py__class__() for c_set in self.get_mapping_item_contexts()) + + class Sequence(BuiltinOverwrite, IterableMixin): api_type = u'instance' @@ -198,11 +203,17 @@ class Sequence(BuiltinOverwrite, IterableMixin): def name(self): return compiled.CompiledContextName(self, self.array_type) + def _get_generics(self): + return (self.merge_types_of_iterate().py__class__(),) + @memoize_method def get_object(self): + from jedi.evaluate.context.typing import AnnotatedSubClass klass = compiled.builtin_from_name(self.evaluator, self.array_type) - instance, = klass.execute_evaluated(self) - return instance + return AnnotatedSubClass( + self.evaluator, klass.parent_context, klass.tree_node, + self._get_generics() + ).execute_annotation() def py__bool__(self): return None # We don't know the length, because of appends. @@ -237,7 +248,7 @@ class SetComprehension(ComprehensionMixin, Sequence): array_type = u'set' -class DictComprehension(ComprehensionMixin, Sequence): +class DictComprehension(_DictMixin, ComprehensionMixin, Sequence): array_type = u'dict' def _get_comp_for(self): @@ -413,7 +424,7 @@ class SequenceLiteralContext(Sequence): return "<%s of %s>" % (self.__class__.__name__, self.atom) -class DictLiteralContext(SequenceLiteralContext): +class DictLiteralContext(_DictMixin, SequenceLiteralContext): array_type = u'dict' def __init__(self, evaluator, defining_context, atom): @@ -479,7 +490,7 @@ class FakeSequence(_FakeArray): return "<%s of %s>" % (type(self).__name__, self._lazy_context_list) -class FakeDict(_FakeArray): +class FakeDict(_DictMixin, _FakeArray): def __init__(self, evaluator, dct): super(FakeDict, self).__init__(evaluator, dct, u'dict') self._dct = dct diff --git a/jedi/evaluate/param.py b/jedi/evaluate/param.py index d00e8116..cadfedb7 100644 --- a/jedi/evaluate/param.py +++ b/jedi/evaluate/param.py @@ -1,5 +1,6 @@ from collections import defaultdict +from jedi import debug from jedi.evaluate.utils import PushBackIterator from jedi.evaluate import analysis from jedi.evaluate.lazy_context import LazyKnownContext, \ @@ -49,9 +50,12 @@ class ExecutedParam(object): # If we cannot infer annotations - or there aren't any - pretend # that the signature matches. return True - return any(c1.is_sub_class_of(c2) - for c1 in argument_contexts - for c2 in annotations) + matches = any(c1.is_sub_class_of(c2) + for c1 in argument_contexts + for c2 in annotations) + debug.dbg("signature compare %s: %s <=> %s", + matches, argument_contexts, annotations, color='BLUE') + return matches @property def var_args(self):