diff --git a/jedi/evaluate/context/function.py b/jedi/evaluate/context/function.py index 9725b64e..ad1069d1 100644 --- a/jedi/evaluate/context/function.py +++ b/jedi/evaluate/context/function.py @@ -123,12 +123,18 @@ class FunctionContext(use_metaclass(CachedMetaClass, AbstractFunction)): def py__class__(self): return compiled.get_special_object(self.evaluator, u'FUNCTION_CLASS') + def get_default_param_context(self): + return self.parent_context + class MethodContext(FunctionContext): def __init__(self, evaluator, class_context, *args, **kwargs): super(MethodContext, self).__init__(evaluator, *args, **kwargs) self.class_context = class_context + def get_default_param_context(self): + return self.class_context + class FunctionExecutionContext(TreeContext): """ @@ -192,11 +198,6 @@ class FunctionExecutionContext(TreeContext): break return context_set - def get_default_param_context(self): - if isinstance(self.function_context, MethodContext): - return self.function_context.class_context - return self.parent_context - def _get_yield_lazy_context(self, yield_expr): if yield_expr.type == 'keyword': # `yield` just yields None. diff --git a/jedi/evaluate/context/typing.py b/jedi/evaluate/context/typing.py index d9ad1f01..cc5bc488 100644 --- a/jedi/evaluate/context/typing.py +++ b/jedi/evaluate/context/typing.py @@ -304,7 +304,7 @@ class TypeVar(Context): return NO_CONTEXTS def __repr__(self): - return '<%s: %s>' % (self.__class__.__name__, self._name) + return '<%s: %s>' % (self.__class__.__name__, self.string_name) class OverloadFunction(_BaseTypingContext): @@ -325,7 +325,7 @@ class BoundTypeVarName(AbstractNameDefinition): self._context_set = context_set def infer(self): - return self._context_set.execute_annotation() + return self._context_set class TypeVarFilter(object): @@ -378,9 +378,10 @@ class AnnotatedClass(ClassContext): @evaluator_method_cache() def find_annotation_variables(self): + found = [] arglist = self.tree_node.get_super_arglist() if arglist is None: - return + return [] for stars, node in unpack_arglist(arglist): if stars: @@ -391,8 +392,9 @@ class AnnotatedClass(ClassContext): if trailer.type == 'trailer' and trailer.children[0] == '[': type_var_set = self.parent_context.eval_node(trailer.children[1]) for type_var in type_var_set: - if isinstance(type_var, TypeVar): - yield type_var + if isinstance(type_var, TypeVar) and type_var not in found: + found.append(type_var) + return found def __repr__(self): return '<%s: %s[%s]>' % ( diff --git a/jedi/evaluate/pep0484.py b/jedi/evaluate/pep0484.py index c857d67e..470ed624 100644 --- a/jedi/evaluate/pep0484.py +++ b/jedi/evaluate/pep0484.py @@ -168,10 +168,11 @@ def infer_param(execution_context, param): param_comment = params_comments[index] return _evaluate_annotation_string( - execution_context.get_root_context(), + execution_context.function_context.get_default_param_context(), param_comment ) - module_context = execution_context.get_root_context() + # Annotations are like default params and resolve in the same way. + module_context = execution_context.function_context.get_default_param_context() return _evaluate_for_annotation(module_context, annotation) @@ -207,11 +208,11 @@ def infer_return_types(function_context): return NO_CONTEXTS return _evaluate_annotation_string( - function_context.get_root_context(), + function_context.get_default_param_context(), match.group(1).strip() ) - module_context = function_context.get_root_context() + module_context = function_context.get_default_param_context() return _evaluate_for_annotation(module_context, annotation)