From 5f613ece287a7f389b79f44d23a24c2aa269ed7c Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Fri, 29 Sep 2017 15:31:21 +0200 Subject: [PATCH] Move the namespace to a separate module. --- jedi/evaluate/context/namespace.py | 75 ++++++++++++++++++++++++++++++ jedi/evaluate/imports.py | 4 +- jedi/evaluate/representation.py | 66 -------------------------- 3 files changed, 77 insertions(+), 68 deletions(-) create mode 100644 jedi/evaluate/context/namespace.py diff --git a/jedi/evaluate/context/namespace.py b/jedi/evaluate/context/namespace.py new file mode 100644 index 00000000..3229b9fb --- /dev/null +++ b/jedi/evaluate/context/namespace.py @@ -0,0 +1,75 @@ +import os +from itertools import chain + +from jedi._compatibility import use_metaclass +from jedi.evaluate.cache import evaluator_method_cache, CachedMetaClass +from jedi.evaluate import imports +from jedi.evaluate.filters import DictFilter, AbstractNameDefinition +from jedi.evaluate import context +from jedi.evaluate.context import NO_CONTEXTS + + +class ImplicitNSName(AbstractNameDefinition): + """ + Accessing names for implicit namespace packages should infer to nothing. + This object will prevent Jedi from raising exceptions + """ + def __init__(self, implicit_ns_context, string_name): + self.implicit_ns_context = implicit_ns_context + self.string_name = string_name + + def infer(self): + return NO_CONTEXTS + + def get_root_context(self): + return self.implicit_ns_context + + +class ImplicitNamespaceContext(use_metaclass(CachedMetaClass, context.TreeContext)): + """ + Provides support for implicit namespace packages + """ + api_type = 'module' + parent_context = None + + def __init__(self, evaluator, fullname): + super(ImplicitNamespaceContext, self).__init__(evaluator, parent_context=None) + self.evaluator = evaluator + self.fullname = fullname + + def get_filters(self, search_global, until_position=None, origin_scope=None): + yield DictFilter(self._sub_modules_dict()) + + @property + @evaluator_method_cache() + def name(self): + string_name = self.py__package__().rpartition('.')[-1] + return ImplicitNSName(self, string_name) + + def py__file__(self): + return None + + def py__package__(self): + """Return the fullname + """ + return self.fullname + + @property + def py__path__(self): + return lambda: [self.paths] + + @evaluator_method_cache() + def _sub_modules_dict(self): + names = {} + + paths = self.paths + file_names = chain.from_iterable(os.listdir(path) for path in paths) + mods = [ + file_name.rpartition('.')[0] if '.' in file_name else file_name + for file_name in file_names + if file_name != '__pycache__' + ] + + for name in mods: + names[name] = imports.SubModuleName(self, name) + return names diff --git a/jedi/evaluate/imports.py b/jedi/evaluate/imports.py index 0478cd4b..745be903 100644 --- a/jedi/evaluate/imports.py +++ b/jedi/evaluate/imports.py @@ -375,7 +375,7 @@ class Importer(object): module_file.close() if isinstance(module_path, ImplicitNSInfo): - from jedi.evaluate.representation import ImplicitNamespaceContext + from jedi.evaluate.context.namespace import ImplicitNamespaceContext fullname, paths = module_path.name, module_path.paths module = ImplicitNamespaceContext(self._evaluator, fullname=fullname) module.paths = paths @@ -421,7 +421,7 @@ class Importer(object): definition that is not defined in a module. """ from jedi.evaluate.context.module import ModuleContext - from jedi.evaluate.representation import ImplicitNamespaceContext + from jedi.evaluate.context.namespace import ImplicitNamespaceContext names = [] if self.import_path: # flask diff --git a/jedi/evaluate/representation.py b/jedi/evaluate/representation.py index 91249616..3b6856d1 100644 --- a/jedi/evaluate/representation.py +++ b/jedi/evaluate/representation.py @@ -198,69 +198,3 @@ class ClassContext(use_metaclass(CachedMetaClass, context.TreeContext)): @property def name(self): return ContextName(self, self.tree_node.name) - - -class ImplicitNSName(AbstractNameDefinition): - """ - Accessing names for implicit namespace packages should infer to nothing. - This object will prevent Jedi from raising exceptions - """ - def __init__(self, implicit_ns_context, string_name): - self.implicit_ns_context = implicit_ns_context - self.string_name = string_name - - def infer(self): - return NO_CONTEXTS - - def get_root_context(self): - return self.implicit_ns_context - - -class ImplicitNamespaceContext(use_metaclass(CachedMetaClass, context.TreeContext)): - """ - Provides support for implicit namespace packages - """ - api_type = 'module' - parent_context = None - - def __init__(self, evaluator, fullname): - super(ImplicitNamespaceContext, self).__init__(evaluator, parent_context=None) - self.evaluator = evaluator - self.fullname = fullname - - def get_filters(self, search_global, until_position=None, origin_scope=None): - yield DictFilter(self._sub_modules_dict()) - - @property - @evaluator_method_cache() - def name(self): - string_name = self.py__package__().rpartition('.')[-1] - return ImplicitNSName(self, string_name) - - def py__file__(self): - return None - - def py__package__(self): - """Return the fullname - """ - return self.fullname - - @property - def py__path__(self): - return lambda: [self.paths] - - @evaluator_method_cache() - def _sub_modules_dict(self): - names = {} - - paths = self.paths - file_names = chain.from_iterable(os.listdir(path) for path in paths) - mods = [ - file_name.rpartition('.')[0] if '.' in file_name else file_name - for file_name in file_names - if file_name != '__pycache__' - ] - - for name in mods: - names[name] = imports.SubModuleName(self, name) - return names