From 1948f23fb3a4e145ef8e6475c758fa67179135f4 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Wed, 21 Nov 2018 23:47:40 +0100 Subject: [PATCH] Fix some issues around stub methods --- jedi/evaluate/context/__init__.py | 3 +- jedi/plugins/typeshed.py | 46 ++++++++++++++++++++++--------- 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/jedi/evaluate/context/__init__.py b/jedi/evaluate/context/__init__.py index 4e7ce4d6..56f6495b 100644 --- a/jedi/evaluate/context/__init__.py +++ b/jedi/evaluate/context/__init__.py @@ -1,5 +1,6 @@ from jedi.evaluate.context.module import ModuleContext from jedi.evaluate.context.klass import ClassContext -from jedi.evaluate.context.function import FunctionContext, FunctionExecutionContext +from jedi.evaluate.context.function import FunctionContext, \ + MethodContext, FunctionExecutionContext from jedi.evaluate.context.instance import AnonymousInstance, BoundMethod, \ CompiledInstance, AbstractInstanceContext, TreeInstance diff --git a/jedi/plugins/typeshed.py b/jedi/plugins/typeshed.py index 810eb277..3bbae623 100644 --- a/jedi/plugins/typeshed.py +++ b/jedi/plugins/typeshed.py @@ -11,14 +11,14 @@ from jedi.evaluate.base_context import ContextSet, iterator_to_context_set, \ from jedi.evaluate.filters import ParserTreeFilter, \ NameWrapper, AbstractFilter, TreeNameDefinition from jedi.evaluate.context import ModuleContext, FunctionContext, \ - ClassContext + MethodContext, ClassContext from jedi.evaluate.context.function import FunctionMixin from jedi.evaluate.context.klass import ClassMixin from jedi.evaluate.context.typing import TypingModuleFilterWrapper, \ TypingModuleName from jedi.evaluate.compiled.context import CompiledName, CompiledObject -from jedi.evaluate.utils import to_list - +from jedi.evaluate.signature import TreeSignature +from jedi.evaluate.utils import to_list, safe_property _jedi_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) _TYPESHED_PATH = os.path.join(_jedi_path, 'third_party', 'typeshed') @@ -197,7 +197,12 @@ class NameWithStubMixin(object): for stub_context in stub_contexts: if isinstance(stub_context, FunctionContext) \ and isinstance(actual_context, FunctionContext): - yield StubFunctionContext.create_cached( + if isinstance(actual_context, MethodContext): + assert isinstance(stub_context, MethodContext) + cls = StubMethodContext + else: + cls = StubFunctionContext + yield cls.create_cached( actual_context.evaluator, self.parent_context, actual_context, @@ -403,19 +408,23 @@ class StubModuleContext(_MixedStubContextMixin, _StubContextFilterMixin, ModuleC class StubClassContext(_StubContextFilterMixin, ClassMixin, ContextWrapper): - def __init__(self, parent_context, cls, stub_context): - super(StubClassContext, self).__init__(cls) + def __init__(self, parent_context, actual_context, stub_context): + super(StubClassContext, self).__init__(actual_context) self.parent_context = parent_context self.stub_context = stub_context def __getattribute__(self, name): if name in ('py__getitem__', 'py__simple_getitem__', 'py__bases__', - 'execute_annotation', 'list_type_vars', 'define_generics', - 'get_signatures'): + 'execute_annotation', 'list_type_vars', 'get_signatures'): # getitem is always done in the stub class. return getattr(self.stub_context, name) return super(StubClassContext, self).__getattribute__(name) + def define_generics(self, type_var_dict): + if not type_var_dict: + return self + return self.stub_context.define_generics(type_var_dict) + class StubFunctionContext(FunctionMixin, ContextWrapper): def __init__(self, parent_context, actual_context, stub_context): @@ -426,11 +435,22 @@ class StubFunctionContext(FunctionMixin, ContextWrapper): def get_function_execution(self, arguments=None): return self.stub_context.get_function_execution(arguments) - def __getattribute__(self, name): - if name == 'get_signatures': - # getitem is always done in the stub class. - return getattr(self.stub_context, name) - return super(StubFunctionContext, self).__getattribute__(name) + def get_signatures(self): + return self.stub_context.get_signatures() + + +class StubMethodContext(StubFunctionContext): + """ + Both of the stub context and the actual context are a stub method. + """ + @safe_property + def class_context(self): + return StubClassContext.create_cached( + self.evaluator, + self.parent_context, + actual_context=self._wrapped_context.class_context, + stub_context=self.stub_context.class_context + ) class _StubOnlyContextMixin(object):