forked from VimPlug/jedi
StubModuleContext is now a wrapped context
This commit is contained in:
@@ -38,27 +38,7 @@ class ModuleName(ContextNameMixin, AbstractNameDefinition):
|
|||||||
return self._name
|
return self._name
|
||||||
|
|
||||||
|
|
||||||
class ModuleContext(TreeContext):
|
class ModuleMixin(object):
|
||||||
api_type = u'module'
|
|
||||||
parent_context = None
|
|
||||||
|
|
||||||
def __init__(self, evaluator, module_node, path, string_names, code_lines):
|
|
||||||
super(ModuleContext, self).__init__(
|
|
||||||
evaluator,
|
|
||||||
parent_context=None,
|
|
||||||
tree_node=module_node
|
|
||||||
)
|
|
||||||
self._path = path
|
|
||||||
self._string_names = string_names
|
|
||||||
self.code_lines = code_lines
|
|
||||||
|
|
||||||
def is_module(self):
|
|
||||||
return True
|
|
||||||
|
|
||||||
def iter_star_filters(self, search_global=False):
|
|
||||||
for star_module in self.star_imports():
|
|
||||||
yield next(star_module.get_filters(search_global))
|
|
||||||
|
|
||||||
def get_filters(self, search_global=False, until_position=None, origin_scope=None):
|
def get_filters(self, search_global=False, until_position=None, origin_scope=None):
|
||||||
yield MergedFilter(
|
yield MergedFilter(
|
||||||
ParserTreeFilter(
|
ParserTreeFilter(
|
||||||
@@ -74,6 +54,67 @@ class ModuleContext(TreeContext):
|
|||||||
for star_filter in self.iter_star_filters():
|
for star_filter in self.iter_star_filters():
|
||||||
yield star_filter
|
yield star_filter
|
||||||
|
|
||||||
|
def py__class__(self):
|
||||||
|
return compiled.get_special_object(self.evaluator, u'MODULE_CLASS')
|
||||||
|
|
||||||
|
def is_module(self):
|
||||||
|
return True
|
||||||
|
|
||||||
|
@property
|
||||||
|
@evaluator_method_cache()
|
||||||
|
def name(self):
|
||||||
|
return ModuleName(self, self._string_name)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _string_name(self):
|
||||||
|
""" This is used for the goto functions. """
|
||||||
|
# TODO It's ugly that we even use this, the name is usually well known
|
||||||
|
# ahead so just pass it when create a ModuleContext.
|
||||||
|
if self._path is None:
|
||||||
|
return '' # no path -> empty name
|
||||||
|
else:
|
||||||
|
sep = (re.escape(os.path.sep),) * 2
|
||||||
|
r = re.search(r'([^%s]*?)(%s__init__)?(\.pyi?|\.so)?$' % sep, self._path)
|
||||||
|
# Remove PEP 3149 names
|
||||||
|
return re.sub(r'\.[a-z]+-\d{2}[mud]{0,3}$', '', r.group(1))
|
||||||
|
|
||||||
|
@evaluator_method_cache()
|
||||||
|
def _sub_modules_dict(self):
|
||||||
|
"""
|
||||||
|
Lists modules in the directory of this module (if this module is a
|
||||||
|
package).
|
||||||
|
"""
|
||||||
|
names = {}
|
||||||
|
try:
|
||||||
|
method = self.py__path__
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
for path in method():
|
||||||
|
mods = iter_modules([path])
|
||||||
|
for module_loader, name, is_pkg in mods:
|
||||||
|
# It's obviously a relative import to the current module.
|
||||||
|
names[name] = SubModuleName(self, name)
|
||||||
|
|
||||||
|
# TODO add something like this in the future, its cleaner than the
|
||||||
|
# import hacks.
|
||||||
|
# ``os.path`` is a hardcoded exception, because it's a
|
||||||
|
# ``sys.modules`` modification.
|
||||||
|
# if str(self.name) == 'os':
|
||||||
|
# names.append(Name('path', parent_context=self))
|
||||||
|
|
||||||
|
return names
|
||||||
|
|
||||||
|
@evaluator_method_cache()
|
||||||
|
def _module_attributes_dict(self):
|
||||||
|
names = ['__file__', '__package__', '__doc__', '__name__']
|
||||||
|
# All the additional module attributes are strings.
|
||||||
|
return dict((n, _ModuleAttributeName(self, n)) for n in names)
|
||||||
|
|
||||||
|
def iter_star_filters(self, search_global=False):
|
||||||
|
for star_module in self.star_imports():
|
||||||
|
yield next(star_module.get_filters(search_global))
|
||||||
|
|
||||||
# I'm not sure if the star import cache is really that effective anymore
|
# I'm not sure if the star import cache is really that effective anymore
|
||||||
# with all the other really fast import caches. Recheck. Also we would need
|
# with all the other really fast import caches. Recheck. Also we would need
|
||||||
# to push the star imports into Evaluator.module_cache, if we reenable this.
|
# to push the star imports into Evaluator.module_cache, if we reenable this.
|
||||||
@@ -90,29 +131,21 @@ class ModuleContext(TreeContext):
|
|||||||
modules += new
|
modules += new
|
||||||
return modules
|
return modules
|
||||||
|
|
||||||
@evaluator_method_cache()
|
|
||||||
def _module_attributes_dict(self):
|
|
||||||
names = ['__file__', '__package__', '__doc__', '__name__']
|
|
||||||
# All the additional module attributes are strings.
|
|
||||||
return dict((n, _ModuleAttributeName(self, n)) for n in names)
|
|
||||||
|
|
||||||
@property
|
class ModuleContext(ModuleMixin, TreeContext):
|
||||||
def _string_name(self):
|
api_type = u'module'
|
||||||
""" This is used for the goto functions. """
|
parent_context = None
|
||||||
# TODO It's ugly that we even use this, the name is usually well known
|
|
||||||
# ahead so just pass it when create a ModuleContext.
|
|
||||||
if self._path is None:
|
|
||||||
return '' # no path -> empty name
|
|
||||||
else:
|
|
||||||
sep = (re.escape(os.path.sep),) * 2
|
|
||||||
r = re.search(r'([^%s]*?)(%s__init__)?(\.pyi?|\.so)?$' % sep, self._path)
|
|
||||||
# Remove PEP 3149 names
|
|
||||||
return re.sub(r'\.[a-z]+-\d{2}[mud]{0,3}$', '', r.group(1))
|
|
||||||
|
|
||||||
@property
|
def __init__(self, evaluator, module_node, path, string_names, code_lines):
|
||||||
@evaluator_method_cache()
|
super(ModuleContext, self).__init__(
|
||||||
def name(self):
|
evaluator,
|
||||||
return ModuleName(self, self._string_name)
|
parent_context=None,
|
||||||
|
tree_node=module_node
|
||||||
|
)
|
||||||
|
self._path = path
|
||||||
|
self._string_names = string_names
|
||||||
|
self.code_lines = code_lines
|
||||||
|
#print(self._path)
|
||||||
|
|
||||||
def _get_init_directory(self):
|
def _get_init_directory(self):
|
||||||
"""
|
"""
|
||||||
@@ -189,36 +222,6 @@ class ModuleContext(TreeContext):
|
|||||||
else:
|
else:
|
||||||
return self._py__path__
|
return self._py__path__
|
||||||
|
|
||||||
@evaluator_method_cache()
|
|
||||||
def _sub_modules_dict(self):
|
|
||||||
"""
|
|
||||||
Lists modules in the directory of this module (if this module is a
|
|
||||||
package).
|
|
||||||
"""
|
|
||||||
names = {}
|
|
||||||
try:
|
|
||||||
method = self.py__path__
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
for path in method():
|
|
||||||
mods = iter_modules([path])
|
|
||||||
for module_loader, name, is_pkg in mods:
|
|
||||||
# It's obviously a relative import to the current module.
|
|
||||||
names[name] = SubModuleName(self, name)
|
|
||||||
|
|
||||||
# TODO add something like this in the future, its cleaner than the
|
|
||||||
# import hacks.
|
|
||||||
# ``os.path`` is a hardcoded exception, because it's a
|
|
||||||
# ``sys.modules`` modification.
|
|
||||||
# if str(self.name) == 'os':
|
|
||||||
# names.append(Name('path', parent_context=self))
|
|
||||||
|
|
||||||
return names
|
|
||||||
|
|
||||||
def py__class__(self):
|
|
||||||
return compiled.get_special_object(self.evaluator, u'MODULE_CLASS')
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<%s: %s@%s-%s is_stub=%s>" % (
|
return "<%s: %s@%s-%s is_stub=%s>" % (
|
||||||
self.__class__.__name__, self._string_name,
|
self.__class__.__name__, self._string_name,
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ from jedi.evaluate.context import ModuleContext, FunctionContext, \
|
|||||||
MethodContext, ClassContext
|
MethodContext, ClassContext
|
||||||
from jedi.evaluate.context.function import FunctionMixin
|
from jedi.evaluate.context.function import FunctionMixin
|
||||||
from jedi.evaluate.context.klass import ClassMixin
|
from jedi.evaluate.context.klass import ClassMixin
|
||||||
|
from jedi.evaluate.context.module import ModuleMixin
|
||||||
from jedi.evaluate.context.typing import TypingModuleFilterWrapper, \
|
from jedi.evaluate.context.typing import TypingModuleFilterWrapper, \
|
||||||
TypingModuleName
|
TypingModuleName
|
||||||
from jedi.evaluate.compiled.context import CompiledObject, CompiledName
|
from jedi.evaluate.compiled.context import CompiledObject, CompiledName
|
||||||
@@ -87,14 +88,7 @@ def _merge_modules(context_set, stub_context):
|
|||||||
|
|
||||||
for context in context_set:
|
for context in context_set:
|
||||||
if isinstance(context, ModuleContext):
|
if isinstance(context, ModuleContext):
|
||||||
yield StubModuleContext(
|
yield StubModuleContext.create_cached(context.evaluator, context, stub_context)
|
||||||
context.evaluator,
|
|
||||||
stub_context,
|
|
||||||
context.tree_node,
|
|
||||||
path=context._path,
|
|
||||||
string_names=context._string_names,
|
|
||||||
code_lines=context.code_lines
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
# TODO do we want this? This includes compiled?!
|
# TODO do we want this? This includes compiled?!
|
||||||
yield stub_context
|
yield stub_context
|
||||||
@@ -386,15 +380,6 @@ class StubFilter(AbstractFilter):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class _MixedStubContextMixin(object):
|
|
||||||
"""
|
|
||||||
Mixes the actual contexts with the stub module contexts.
|
|
||||||
"""
|
|
||||||
def __init__(self, evaluator, stub_context, *args, **kwargs):
|
|
||||||
super(_MixedStubContextMixin, self).__init__(evaluator, *args, **kwargs)
|
|
||||||
self.stub_context = stub_context
|
|
||||||
|
|
||||||
|
|
||||||
class _StubContextFilterMixin(object):
|
class _StubContextFilterMixin(object):
|
||||||
def get_filters(self, search_global=False, until_position=None,
|
def get_filters(self, search_global=False, until_position=None,
|
||||||
origin_scope=None, **kwargs):
|
origin_scope=None, **kwargs):
|
||||||
@@ -414,11 +399,10 @@ class _StubContextFilterMixin(object):
|
|||||||
yield f
|
yield f
|
||||||
|
|
||||||
|
|
||||||
class StubModuleContext(_MixedStubContextMixin, _StubContextFilterMixin, ModuleContext):
|
class StubModuleContext(_StubContextFilterMixin, ModuleMixin, ContextWrapper):
|
||||||
@property
|
def __init__(self, context, stub_context):
|
||||||
def _wrapped_context(self):
|
super(StubModuleContext, self).__init__(context)
|
||||||
# TODO this is stupid.
|
self.stub_context = stub_context
|
||||||
return super(_StubContextFilterMixin, self)
|
|
||||||
|
|
||||||
|
|
||||||
class StubClassContext(_StubContextFilterMixin, ClassMixin, ContextWrapper):
|
class StubClassContext(_StubContextFilterMixin, ClassMixin, ContextWrapper):
|
||||||
|
|||||||
Reference in New Issue
Block a user