Get an own class for type aliases

This commit is contained in:
Dave Halter
2018-08-29 22:46:28 +02:00
parent 0edfe86d8b
commit 511ba5231a
3 changed files with 50 additions and 15 deletions

View File

@@ -233,7 +233,7 @@ class Completion:
) )
contexts = evaluate_call_of_leaf(evaluation_context, previous_leaf) contexts = evaluate_call_of_leaf(evaluation_context, previous_leaf)
completion_names = [] completion_names = []
debug.dbg('trailer completion contexts: %s', contexts) debug.dbg('trailer completion contexts: %s', contexts, color='MAGENTA')
for context in contexts: for context in contexts:
for filter in context.get_filters( for filter in context.get_filters(
search_global=False, origin_scope=user_context.tree_node): search_global=False, origin_scope=user_context.tree_node):

View File

@@ -397,6 +397,9 @@ class LazyInstanceClassName(object):
def __getattr__(self, name): def __getattr__(self, name):
return getattr(self._class_member_name, name) return getattr(self._class_member_name, name)
def __repr__(self):
return '<%s: %s>' % (self.__class__.__name__, self._class_member_name)
class InstanceClassFilter(filters.AbstractFilter): class InstanceClassFilter(filters.AbstractFilter):
""" """

View File

@@ -12,7 +12,7 @@ from jedi.evaluate.context.iterable import SequenceLiteralContext
from jedi.evaluate.arguments import repack_with_argument_clinic, unpack_arglist from jedi.evaluate.arguments import repack_with_argument_clinic, unpack_arglist
from jedi.evaluate.utils import to_list from jedi.evaluate.utils import to_list
from jedi.evaluate.filters import FilterWrapper, NameWrapper, \ from jedi.evaluate.filters import FilterWrapper, NameWrapper, \
AbstractTreeName, AbstractNameDefinition AbstractTreeName, AbstractNameDefinition, ContextName
from jedi.evaluate.helpers import is_string from jedi.evaluate.helpers import is_string
from jedi.evaluate.imports import Importer from jedi.evaluate.imports import Importer
from jedi.evaluate.context import ClassContext from jedi.evaluate.context import ClassContext
@@ -79,7 +79,15 @@ class TypingModuleName(NameWrapper):
# TODO we don't want the SpecialForm bullshit # TODO we don't want the SpecialForm bullshit
name = self.string_name name = self.string_name
evaluator = self.parent_context.evaluator evaluator = self.parent_context.evaluator
if name in (_PROXY_CLASS_TYPES + list(_TYPE_ALIAS_TYPES)): try:
actual = _TYPE_ALIAS_TYPES[name]
except KeyError:
pass
else:
yield TypeAlias(evaluator, name, actual)
return
if name in _PROXY_CLASS_TYPES:
yield TypingClassContext(self) yield TypingClassContext(self)
elif name in _PROXY_TYPES: elif name in _PROXY_TYPES:
yield TypingContext(self) yield TypingContext(self)
@@ -161,8 +169,10 @@ class TypingContextWithIndex(_WithIndexBase):
# For now don't do anything here, ClassVars are always used. # For now don't do anything here, ClassVars are always used.
return self._context.execute_annotation() return self._context.execute_annotation()
cls = globals()[string_name]
return ContextSet(cls(self._name, self._index_context, self._context_of_index))
try: try:
alias = _TYPE_ALIAS_TYPES[string_name] alias = _TYPE_ALIAS_TYPES[string_name]
except KeyError: except KeyError:
cls = globals()[string_name] cls = globals()[string_name]
return ContextSet(cls(self._name, self._index_context, self._context_of_index)) return ContextSet(cls(self._name, self._index_context, self._context_of_index))
@@ -170,7 +180,6 @@ class TypingContextWithIndex(_WithIndexBase):
module_name, class_name = alias.split('.') module_name, class_name = alias.split('.')
cls = _find_type_alias_class( cls = _find_type_alias_class(
self.evaluator, self.evaluator,
self.get_root_context(),
module_name, module_name,
class_name class_name
) )
@@ -233,17 +242,40 @@ def _iter_over_arguments(maybe_tuple_context, defining_context):
yield ContextSet.from_iterable(resolve_forward_references(context_set)) yield ContextSet.from_iterable(resolve_forward_references(context_set))
def _find_type_alias_class(evaluator, module_context, module_name, class_name): class TypeAlias(object):
if evaluator.environment.version_info.major == 2 and module_name == 'builtins': def __init__(self, evaluator, origin_name, actual):
module_name = '__builtin__' self.evaluator = evaluator
self._origin_name = origin_name
self._actual = actual # e.g. builtins.list
module, = Importer(evaluator, [module_name], module_context).follow() @property
classes = module.py__getattribute__(class_name) def name(self):
# There should only be one, because it's code that we control. return ContextName(self, self._origin_name.tree_name)
assert len(classes) == 1, classes
cls = next(iter(classes)) def py__name__(self):
assert isinstance(cls, ClassContext), cls return self.name.string_name
return cls
def __getattr__(self, name):
return getattr(self._get_type_alias_class(), name)
def __repr__(self):
return '<%s: %s>' % (self.__class__.__name__, self._actual)
@evaluator_method_cache()
def _get_type_alias_class(self):
module_name, class_name = self._actual.split('.')
if self.evaluator.environment.version_info.major == 2 and module_name == 'builtins':
module_name = '__builtin__'
module, = Importer(
self.evaluator, [module_name], self.evaluator.builtins_module
).follow()
classes = module.py__getattribute__(class_name)
# There should only be one, because it's code that we control.
assert len(classes) == 1, classes
cls = next(iter(classes))
assert isinstance(cls, ClassContext), cls
return cls
class _ContainerBase(_WithIndexBase): class _ContainerBase(_WithIndexBase):