diff --git a/jedi/evaluate/base_context.py b/jedi/evaluate/base_context.py index e85ce010..78db6615 100644 --- a/jedi/evaluate/base_context.py +++ b/jedi/evaluate/base_context.py @@ -77,7 +77,7 @@ class Context(BaseContext): # The actual getitem call. try: - getitem = self.py__getitem__ + getitem = self.py__simple_getitem__ except AttributeError: from jedi.evaluate import analysis # TODO this context is probably not right. diff --git a/jedi/evaluate/compiled/access.py b/jedi/evaluate/compiled/access.py index ab1d3545..25b624f7 100644 --- a/jedi/evaluate/compiled/access.py +++ b/jedi/evaluate/compiled/access.py @@ -226,7 +226,7 @@ class DirectObjectAccess(object): def py__mro__accesses(self): return tuple(self._create_access_path(cls) for cls in self._obj.__mro__[1:]) - def py__getitem__(self, index): + def py__simple_getitem__(self, index): if type(self._obj) not in (str, list, tuple, unicode, bytes, bytearray, dict): # Get rid of side effects, we won't call custom `__getitem__`s. return None diff --git a/jedi/evaluate/compiled/context.py b/jedi/evaluate/compiled/context.py index 31f8c268..87e9c20d 100644 --- a/jedi/evaluate/compiled/context.py +++ b/jedi/evaluate/compiled/context.py @@ -19,10 +19,15 @@ from . import fake class CheckAttribute(object): """Raises an AttributeError if the attribute X isn't available.""" - def __init__(self, func): - self.func = func + def __init__(self, check_name=None): # Remove the py in front of e.g. py__call__. - self.check_name = force_unicode(func.__name__[2:]) + self.check_name = check_name + + def __call__(self, func): + self.func = func + if self.check_name is None: + self.check_name = force_unicode(func.__name__[2:]) + return self def __get__(self, instance, owner): if instance is None: @@ -48,7 +53,7 @@ class CompiledObject(Context): # This attribute will not be set for most classes, except for fakes. self.tree_node = faked_class - @CheckAttribute + @CheckAttribute() def py__call__(self, params): if self.tree_node is not None and self.tree_node.type == 'funcdef': from jedi.evaluate.context.function import FunctionContext @@ -63,25 +68,25 @@ class CompiledObject(Context): else: return ContextSet.from_iterable(self._execute_function(params)) - @CheckAttribute + @CheckAttribute() def py__class__(self): return create_from_access_path(self.evaluator, self.access_handle.py__class__()) - @CheckAttribute + @CheckAttribute() def py__mro__(self): return (self,) + tuple( create_from_access_path(self.evaluator, access) for access in self.access_handle.py__mro__accesses() ) - @CheckAttribute + @CheckAttribute() def py__bases__(self): return tuple( create_from_access_path(self.evaluator, access) for access in self.access_handle.py__bases__() ) - @CheckAttribute + @CheckAttribute() def py__path__(self): return self.access_handle.py__path__() @@ -148,16 +153,16 @@ class CompiledObject(Context): """ return CompiledObjectFilter(self.evaluator, self, is_instance) - @CheckAttribute - def py__getitem__(self, index): + @CheckAttribute('__getitem__') + def py__simple_getitem__(self, index): with reraise_as_evaluator(IndexError, KeyError, TypeError): - access = self.access_handle.py__getitem__(index) + access = self.access_handle.py__simple_getitem__(index) if access is None: return ContextSet() return ContextSet(create_from_access_path(self.evaluator, access)) - @CheckAttribute + @CheckAttribute() def py__iter__(self): for access in self.access_handle.py__iter__list(): yield LazyKnownContext(create_from_access_path(self.evaluator, access)) diff --git a/jedi/evaluate/context/instance.py b/jedi/evaluate/context/instance.py index db94c91a..50432432 100644 --- a/jedi/evaluate/context/instance.py +++ b/jedi/evaluate/context/instance.py @@ -126,7 +126,7 @@ class AbstractInstanceContext(Context): else: yield InstanceClassFilter(self.evaluator, self, cls, origin_scope) - def py__getitem__(self, index): + def py__simple_getitem__(self, index): try: names = self.get_function_slot_names(u'__getitem__') except KeyError: diff --git a/jedi/evaluate/context/iterable.py b/jedi/evaluate/context/iterable.py index 622f2304..13ff9451 100644 --- a/jedi/evaluate/context/iterable.py +++ b/jedi/evaluate/context/iterable.py @@ -212,7 +212,7 @@ class Sequence(BuiltinOverwrite, IterableMixin): class ListComprehension(ComprehensionMixin, Sequence): array_type = u'list' - def py__getitem__(self, index): + def py__simple_getitem__(self, index): if isinstance(index, slice): return ContextSet(self) @@ -236,7 +236,7 @@ class DictComprehension(ComprehensionMixin, Sequence): for keys, values in self._iterate(): yield LazyKnownContexts(keys) - def py__getitem__(self, index): + def py__simple_getitem__(self, index): for keys, values in self._iterate(): for k in keys: if isinstance(k, compiled.CompiledObject): @@ -289,7 +289,7 @@ class SequenceLiteralContext(Sequence): self.array_type = SequenceLiteralContext.mapping[atom.children[0]] """The builtin name of the array (list, set, tuple or dict).""" - def py__getitem__(self, index): + def py__simple_getitem__(self, index): """Here the index is an int/str. Raises IndexError/KeyError.""" if self.array_type == u'dict': compiled_obj_index = compiled.create_simple_object(self.evaluator, index) @@ -419,7 +419,7 @@ class FakeSequence(_FakeArray): super(FakeSequence, self).__init__(evaluator, None, array_type) self._lazy_context_list = lazy_context_list - def py__getitem__(self, index): + def py__simple_getitem__(self, index): with reraise_as_evaluator(IndexError, TypeError): lazy_context = self._lazy_context_list[index] return lazy_context.infer() @@ -443,7 +443,7 @@ class FakeDict(_FakeArray): for key in self._dct: yield LazyKnownContext(compiled.create_simple_object(self.evaluator, key)) - def py__getitem__(self, index): + def py__simple_getitem__(self, index): if is_py3 and self.evaluator.environment.version_info.major == 2: # In Python 2 bytes and unicode compare. if isinstance(index, bytes): @@ -487,7 +487,7 @@ class MergedArray(_FakeArray): for lazy_context in array.py__iter__(): yield lazy_context - def py__getitem__(self, index): + def py__simple_getitem__(self, index): return ContextSet.from_sets(lazy_context.infer() for lazy_context in self.py__iter__()) def _items(self): diff --git a/jedi/evaluate/context/klass.py b/jedi/evaluate/context/klass.py index ca17f348..a657ca3b 100644 --- a/jedi/evaluate/context/klass.py +++ b/jedi/evaluate/context/klass.py @@ -24,8 +24,9 @@ py__bases__() Returns a list of base classes. py__mro__() Returns a list of classes (the mro). py__iter__() Returns a generator of a set of types. py__class__() Returns the class of an instance. -py__getitem__(index: int/str) Returns a a set of types of the index. +py__simple_getitem__(index: int/str) Returns a a set of types of the index. Can raise an IndexError/KeyError. +py__getitem__(indexes: ContextSet) Returns a a set of types of the index. py__file__() Only on modules. Returns None if does not exist. py__package__() Only on modules. For the import system. diff --git a/jedi/evaluate/pep0484.py b/jedi/evaluate/pep0484.py index 0477c414..fe5c7b87 100644 --- a/jedi/evaluate/pep0484.py +++ b/jedi/evaluate/pep0484.py @@ -56,7 +56,7 @@ def _evaluate_annotation_string(context, string, index=None): context_set = context_set.filter( lambda context: context.array_type == u'tuple' # noqa and len(list(context.py__iter__())) >= index - ).py__getitem__(index) + ).py__simple_getitem__(index) return context_set.execute_evaluated() @@ -243,7 +243,7 @@ def _get_typing_replacement_module(grammar): return _typing_module, _typing_module_code_lines -def py__getitem__(context, typ, node): +def py__simple_getitem__(context, typ, node): if not typ.get_root_context().name.string_name == "typing": return None # we assume that any class using [] in a module called diff --git a/jedi/evaluate/syntax_tree.py b/jedi/evaluate/syntax_tree.py index 958b5a2a..806f94b4 100644 --- a/jedi/evaluate/syntax_tree.py +++ b/jedi/evaluate/syntax_tree.py @@ -161,7 +161,7 @@ def eval_trailer(context, base_contexts, trailer): result = ContextSet() for typ in list(foo): if isinstance(typ, (ClassContext, TreeInstance)): - typing_module_types = pep0484.py__getitem__(context, typ, node) + typing_module_types = pep0484.py__simple_getitem__(context, typ, node) if typing_module_types is not None: foo.remove(typ) result |= typing_module_types diff --git a/jedi/plugins/flask.py b/jedi/plugins/flask.py index 7a8cd532..e1ee4fb9 100644 --- a/jedi/plugins/flask.py +++ b/jedi/plugins/flask.py @@ -1,5 +1,3 @@ -from parso.python.tree import Name - from jedi.plugins.base import BasePlugin from jedi.evaluate.imports import JediImportError