From 9178d314b0f2aa86d8124dc47fcc330f02cbd1c6 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Tue, 6 Jan 2015 15:30:59 +0100 Subject: [PATCH] Add search_global to names_dicts calls. --- jedi/evaluate/cache.py | 4 ++++ jedi/evaluate/compiled/__init__.py | 2 +- jedi/evaluate/finder.py | 6 +++--- jedi/evaluate/iterable.py | 10 +++++----- jedi/evaluate/representation.py | 26 ++++++++++++++++++-------- 5 files changed, 31 insertions(+), 17 deletions(-) diff --git a/jedi/evaluate/cache.py b/jedi/evaluate/cache.py index 4ee72967..e40c5c8a 100644 --- a/jedi/evaluate/cache.py +++ b/jedi/evaluate/cache.py @@ -4,6 +4,8 @@ - ``CachedMetaClass`` uses ``memoize_default`` to do the same with classes. """ +import inspect + NO_DEFAULT = object() @@ -37,6 +39,8 @@ def memoize_default(default=None, evaluator_is_first_arg=False, second_arg_is_ev if default is not NO_DEFAULT: memo[key] = default rv = function(obj, *args, **kwargs) + if inspect.isgenerator(rv): + rv = list(rv) memo[key] = rv return rv return wrapper diff --git a/jedi/evaluate/compiled/__init__.py b/jedi/evaluate/compiled/__init__.py index 49faa29a..55f74acf 100644 --- a/jedi/evaluate/compiled/__init__.py +++ b/jedi/evaluate/compiled/__init__.py @@ -151,7 +151,7 @@ class CompiledObject(Base): def names_dict(self): return LazyNamesDict(self._cls()) - def names_dicts(self): + def names_dicts(self, search_global): yield self.names_dict def scope_names_generator(self, position=None, add_class_vars=True): diff --git a/jedi/evaluate/finder.py b/jedi/evaluate/finder.py index e5727821..79ab56b9 100644 --- a/jedi/evaluate/finder.py +++ b/jedi/evaluate/finder.py @@ -68,7 +68,7 @@ class NameFinder(object): if search_global: return global_names_dict_generator(self._evaluator, self.scope, self.position) else: - return ((n, None) for n in self.scope.names_dicts()) + return ((n, None) for n in self.scope.names_dicts(search_global)) def names_dict_lookup(self, names_dict, position): def get_param(el): @@ -528,7 +528,7 @@ def global_names_dict_generator(evaluator, scope, position): compiled.CompiledObject) and scope.type() == 'class') and in_func): # Names in methods cannot be resolved within the class. - for names_dict in scope.names_dicts(): + for names_dict in scope.names_dicts(True): yield names_dict, position if scope.type == 'funcdef': # The position should be reset if the current scope is a function. @@ -537,7 +537,7 @@ def global_names_dict_generator(evaluator, scope, position): scope = er.wrap(evaluator, scope.get_parent_scope()) # Add builtins to the global scope. - for names_dict in compiled.builtin.names_dicts(): + for names_dict in compiled.builtin.names_dicts(True): yield names_dict, None diff --git a/jedi/evaluate/iterable.py b/jedi/evaluate/iterable.py index 3ed5ea57..8e767131 100644 --- a/jedi/evaluate/iterable.py +++ b/jedi/evaluate/iterable.py @@ -62,8 +62,8 @@ class GeneratorMixin(object): def scope_names_generator(self, position=None): yield self, self._get_defined_names() - @underscore_memoization - def names_dicts(self): + @memoize_default() + def names_dicts(self, search_global=False): # is always False dct = {} executes_generator = '__next__', 'send', 'next' for name in compiled.generator_obj.get_defined_names(): @@ -269,12 +269,12 @@ class Array(IterableWrapper): for _, names in scope.scope_names_generator(): yield self, names - @underscore_memoization - def names_dicts(self): + @memoize_default() + def names_dicts(self, search_global=False): # Always False. # `array.type` is a string with the type, e.g. 'list'. scope = self._evaluator.find_types(compiled.builtin, self.type)[0] scope = self._evaluator.execute(scope)[0] # builtins only have one class - return scope.names_dicts() + return scope.names_dicts(search_global) @common.safe_property def parent(self): diff --git a/jedi/evaluate/representation.py b/jedi/evaluate/representation.py index f4db1205..9d13c901 100644 --- a/jedi/evaluate/representation.py +++ b/jedi/evaluate/representation.py @@ -238,11 +238,11 @@ class Instance(use_metaclass(CachedMetaClass, Executed)): except KeyError: return [self] - @underscore_memoization - def names_dicts(self): + @memoize_default() + def names_dicts(self, search_global): yield self._self_names_dict() - for names_dict in self.base.names_dicts(): + for names_dict in self.base.names_dicts(search_global=False): yield LazyInstanceDict(self._evaluator, self, names_dict) def scope_names_generator(self, position=None): @@ -425,9 +425,6 @@ class Wrapper(pr.Base): def is_class(self): return False - def names_dicts(self): - yield self.names_dict - @property @underscore_memoization def name(self): @@ -500,6 +497,13 @@ class Class(use_metaclass(CachedMetaClass, Wrapper)): if add_class_vars: yield self, compiled.type_names + def names_dicts(self, search_global): + if search_global: + yield self.names_dict + else: + for scope in self.py__mro__(self._evaluator): + yield scope.names_dict + def is_class(self): return True @@ -586,6 +590,12 @@ class Function(use_metaclass(CachedMetaClass, Wrapper)): debug.dbg('decorator end %s', f) return f + def names_dicts(self, search_global): + if search_global: + yield self.names_dict + else: + raise NotImplementedError + def get_magic_function_names(self): return compiled.magic_function_class.get_defined_names() @@ -699,7 +709,7 @@ class FunctionExecution(Executed): return LazyDict(self.base.names_dict, self._copy_list) """ - def names_dicts(self): + def names_dicts(self, search_global): self.children yield dict((k, [self._copy_dict[v] for v in values]) for k, values in self.base.names_dict.items()) @@ -817,7 +827,7 @@ class ModuleWrapper(use_metaclass(CachedMetaClass, pr.Module, Wrapper)): if sub_modules: yield self, self._sub_modules() - def names_dicts(self): + def names_dicts(self, search_global): yield self.base.names_dict yield self._module_attributes_dict()