Try to re-implement reversed

This commit is contained in:
Dave Halter
2018-09-07 23:00:32 +02:00
parent 9e7879d43f
commit 91a18ec63c
4 changed files with 31 additions and 29 deletions

View File

@@ -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

View File

@@ -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)

View File

@@ -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():

View File

@@ -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: