diff --git a/jedi/evaluate/compiled/__init__.py b/jedi/evaluate/compiled/__init__.py index 92856987..2aca8edc 100644 --- a/jedi/evaluate/compiled/__init__.py +++ b/jedi/evaluate/compiled/__init__.py @@ -225,14 +225,15 @@ class CompiledObject(Base): for name in self._parse_function_doc()[1].split(): try: - bltn_obj = builtin_from_name(evaluator, name) + bltn_obj = getattr(_builtins, name) except AttributeError: continue else: - if bltn_obj.obj is None: + if bltn_obj is None: # We want to evaluate everything except None. # TODO do we? continue + bltn_obj = create(evaluator, bltn_obj) for result in evaluator.execute(bltn_obj, params): yield result @@ -530,11 +531,4 @@ def create(evaluator, obj, parent=None, module=None): faked.parent = parent return faked - # TODO delete - #try: - #if parent == builtin and obj.__module__ in ('builtins', '__builtin__'): - #return builtin.get_by_name(obj.__name__) - #except AttributeError: - #pass - return CompiledObject(evaluator, obj, parent) diff --git a/jedi/evaluate/compiled/fake.py b/jedi/evaluate/compiled/fake.py index 947fef26..eaf099a6 100644 --- a/jedi/evaluate/compiled/fake.py +++ b/jedi/evaluate/compiled/fake.py @@ -65,6 +65,7 @@ def get_module(obj): return builtins else: if imp_plz is None: + # Happens for example in `(_ for _ in []).send.__module__`. return builtins else: return __import__(imp_plz) @@ -77,7 +78,7 @@ def _faked(module, obj, name): faked_mod = _load_faked_module(module) if faked_mod is None: - return + return None # Having the module as a `parser.representation.module`, we need to scan # for methods. @@ -95,12 +96,15 @@ def _faked(module, obj, name): if cls is None: return None return search_scope(cls, obj.__name__) - else: if obj == module: return search_scope(faked_mod, name) else: - cls = search_scope(faked_mod, obj.__name__) + try: + cls_name = obj.__name__ + except AttributeError: + return None + cls = search_scope(faked_mod, cls_name) if cls is None: return None return search_scope(cls, name) diff --git a/jedi/evaluate/iterable.py b/jedi/evaluate/iterable.py index 0e9ff086..0e506862 100644 --- a/jedi/evaluate/iterable.py +++ b/jedi/evaluate/iterable.py @@ -274,6 +274,10 @@ class Array(IterableWrapper, ArrayMixin): result |= check_array_additions(self._evaluator, self) return result + @memoize_default() + def dict_values(self): + return unite(self._evaluator.eval_element(v) for v in self._values()) + def py__getitem__(self, index): """Here the index is an int/str. Raises IndexError/KeyError.""" if self.type == 'dict': @@ -515,7 +519,11 @@ def py__getitem__(evaluator, types, index, node): if type(index) not in (float, int, str, unicode, slice): # If the index is not clearly defined, we have to get all the # possiblities. - return py__iter__types(evaluator, types) + for typ in list(types): + if isinstance(typ, Array) and typ.type == 'dict': + types.remove(typ) + result |= typ.dict_values() + return result | py__iter__types(evaluator, types) for typ in types: # The actual getitem call. @@ -531,7 +539,7 @@ def py__getitem__(evaluator, types, index, node): result |= py__iter__types(evaluator, set([typ])) except KeyError: # Must be a dict. Lists don't raise IndexErrors. - result |= typ.values() + result |= typ.dict_values() return result diff --git a/jedi/evaluate/precedence.py b/jedi/evaluate/precedence.py index 778d3574..5225aa68 100644 --- a/jedi/evaluate/precedence.py +++ b/jedi/evaluate/precedence.py @@ -6,7 +6,7 @@ import operator from jedi._compatibility import unicode from jedi.parser import tree from jedi import debug -from jedi.evaluate.compiled import CompiledObject, create +from jedi.evaluate.compiled import CompiledObject, create, builtin_from_name from jedi.evaluate import analysis # Maps Python syntax to the operator module. @@ -30,7 +30,7 @@ def literals_to_types(evaluator, result): if is_literal(typ): # Literals are only valid as long as the operations are # correct. Otherwise add a value-free instance. - cls = create(evaluator, typ.name.value) + cls = builtin_from_name(evaluator, typ.name.value) new_result |= evaluator.execute(cls) else: new_result.add(typ)