diff --git a/jedi/evaluate/compiled/fake/builtins.pym b/jedi/evaluate/compiled/fake/builtins.pym index 46ec619f..8a31d62f 100644 --- a/jedi/evaluate/compiled/fake/builtins.pym +++ b/jedi/evaluate/compiled/fake/builtins.pym @@ -235,21 +235,6 @@ class enumerate(): return next(self.__iter__()) -class reversed(): - def __init__(self, sequence): - self.__sequence = sequence - - def __iter__(self): - for i in self.__sequence: - yield i - - def __next__(self): - return next(self.__iter__()) - - def next(self): - return next(self.__iter__()) - - def sorted(iterable, cmp=None, key=None, reverse=False): return iterable diff --git a/jedi/evaluate/context/klass.py b/jedi/evaluate/context/klass.py index 3ff8982e..e47cf575 100644 --- a/jedi/evaluate/context/klass.py +++ b/jedi/evaluate/context/klass.py @@ -83,7 +83,7 @@ def py__mro__(context): # TODO detect for TypeError: duplicate base class str, # e.g. `class X(str, str): pass` try: - mro_method = py__mro__(cls) + cls.py__bases__ except AttributeError: # TODO add a TypeError like: """ @@ -99,7 +99,7 @@ def py__mro__(context): debug.warning('Super class of %s is not a class: %s', context, cls) else: add(cls) - for cls_new in mro_method(): + for cls_new in py__mro__(context): add(cls_new) return tuple(mro) diff --git a/jedi/plugins/stdlib.py b/jedi/plugins/stdlib.py index 4f8173aa..c861ef92 100644 --- a/jedi/plugins/stdlib.py +++ b/jedi/plugins/stdlib.py @@ -24,6 +24,7 @@ from jedi.evaluate.base_context import ContextualizedNode, \ NO_CONTEXTS, ContextSet, ContextWrapper from jedi.evaluate.context import ClassContext, ModuleContext, \ FunctionExecutionContext +from jedi.plugins import typeshed from jedi.evaluate.context.klass import py__mro__ from jedi.evaluate.context import iterable from jedi.evaluate.lazy_context import LazyTreeContext @@ -197,11 +198,27 @@ def builtins_super(types, objects, context): return NO_CONTEXTS +class ReversedObject(ContextWrapper): + def __init__(self, reversed_obj, iter_list): + super(ReversedObject, self).__init__(reversed_obj) + self._iter_list = iter_list + + def py__iter__(self): + return self._iter_list + + def py__next__(self): + return ContextSet.from_sets( + lazy_context.infer() for lazy_context in self._iter_list + ) + + @argument_clinic('sequence, /', want_obj=True, want_arguments=True) def builtins_reversed(sequences, obj, arguments): # While we could do without this variable (just by using sequences), we # want static analysis to work well. Therefore we need to generated the # values again. + if not isinstance(obj, typeshed.StubContextWithCompiled): + return obj.py__call__(arguments) key, lazy_context = next(arguments.unpack()) cn = None if isinstance(lazy_context, LazyTreeContext): @@ -209,18 +226,18 @@ def builtins_reversed(sequences, obj, arguments): cn = ContextualizedNode(lazy_context._context, lazy_context.data) ordered = list(sequences.iterate(cn)) - rev = list(reversed(ordered)) # Repack iterator values and then run it the normal way. This is # necessary, because `reversed` is a function and autocompletion # would fail in certain cases like `reversed(x).__iter__` if we # just returned the result directly. - seq = iterable.FakeSequence(obj.evaluator, u'list', rev) - arguments = ValuesArguments([ContextSet(seq)]) - return ContextSet(CompiledInstance( - obj.evaluator, - obj.evaluator.builtins_module, - obj, - arguments + return ContextSet(ReversedObject( + CompiledInstance( + obj.evaluator, + obj.evaluator.builtins_module, + obj.compiled_context, + arguments + ), + list(reversed(ordered)), )) @@ -230,7 +247,7 @@ def builtins_isinstance(objects, types, arguments, evaluator): for o in objects: cls = o.py__class__() try: - mro_func = py__mro__(cls) + cls.py__bases__ except AttributeError: # This is temporary. Everything should have a class attribute in # Python?! Maybe we'll leave it here, because some numpy objects or @@ -238,7 +255,7 @@ def builtins_isinstance(objects, types, arguments, evaluator): bool_results = set([True, False]) break - mro = mro_func() + mro = py__mro__(cls) for cls_or_tup in types: if cls_or_tup.is_class(): diff --git a/jedi/plugins/typeshed.py b/jedi/plugins/typeshed.py index 4b4e0b9d..d7a41901 100644 --- a/jedi/plugins/typeshed.py +++ b/jedi/plugins/typeshed.py @@ -405,10 +405,10 @@ class StubOnlyModuleContext(ModuleContext): class StubContextWithCompiled(ContextWrapper): def __init__(self, stub_context, compiled_context): super(StubContextWithCompiled, self).__init__(stub_context) - self._compiled_context = compiled_context + self.compiled_context = compiled_context def py__doc__(self, include_call_signature=False): - doc = self._compiled_context.py__doc__() + doc = self.compiled_context.py__doc__() if include_call_signature: call_sig = get_call_signature_for_any(self._wrapped_context.tree_node) if call_sig is not None: