forked from VimPlug/jedi
Fix the first issues with the new typing module implementation
This commit is contained in:
@@ -273,6 +273,7 @@ class GeneratorComprehension(ComprehensionMixin, GeneratorBase):
|
||||
|
||||
|
||||
class SequenceLiteralContext(Sequence):
|
||||
_TUPLE_LIKE = 'testlist_star_expr', 'testlist', 'subscriptlist'
|
||||
mapping = {'(': u'tuple',
|
||||
'[': u'list',
|
||||
'{': u'set'}
|
||||
@@ -282,7 +283,7 @@ class SequenceLiteralContext(Sequence):
|
||||
self.atom = atom
|
||||
self._defining_context = defining_context
|
||||
|
||||
if self.atom.type in ('testlist_star_expr', 'testlist'):
|
||||
if self.atom.type in self._TUPLE_LIKE:
|
||||
self.array_type = u'tuple'
|
||||
else:
|
||||
self.array_type = SequenceLiteralContext.mapping[atom.children[0]]
|
||||
@@ -336,7 +337,7 @@ class SequenceLiteralContext(Sequence):
|
||||
def _items(self):
|
||||
c = self.atom.children
|
||||
|
||||
if self.atom.type in ('testlist_star_expr', 'testlist'):
|
||||
if self.atom.type in self._TUPLE_LIKE:
|
||||
return c[::2]
|
||||
|
||||
array_node = c[1]
|
||||
|
||||
@@ -3,6 +3,7 @@ We need to somehow work with the typing objects. Since the typing objects are
|
||||
pretty bare we need to add all the Jedi customizations to make them work as
|
||||
contexts.
|
||||
"""
|
||||
from parso.python import tree
|
||||
|
||||
from jedi import debug
|
||||
from jedi.evaluate.compiled import builtin_from_name
|
||||
@@ -13,10 +14,30 @@ _PROXY_TYPES = 'Optional Union Callable Type ClassVar Tuple Generic Protocol'.sp
|
||||
_TYPE_ALIAS_TYPES = 'List Dict DefaultDict Set FrozenSet Counter Deque ChainMap'.split()
|
||||
|
||||
|
||||
def check(context, name):
|
||||
class _TypingBase(object):
|
||||
def __init__(self, name, typing_context):
|
||||
self._name = name
|
||||
self._context = typing_context
|
||||
|
||||
def __getattr__(self, name):
|
||||
return getattr(self._context, name)
|
||||
|
||||
def __repr__(self):
|
||||
return '%s(%s)' % (self.__class__.__name__, self._context)
|
||||
|
||||
|
||||
class TypingModuleWrapper(_TypingBase):
|
||||
def py__getattribute__(self, name_or_str, *args, **kwargs):
|
||||
result = self._context.py__getattribute__(name_or_str)
|
||||
if kwargs.get('is_goto'):
|
||||
return result
|
||||
name = name_or_str.value if isinstance(name_or_str, tree.Name) else name_or_str
|
||||
return ContextSet.from_iterable(_remap(c, name) for c in result)
|
||||
|
||||
|
||||
def _remap(context, name):
|
||||
if name in _PROXY_TYPES:
|
||||
return TypingProxy(context)
|
||||
return TypingProxy(name, context)
|
||||
elif name in _TYPE_ALIAS_TYPES:
|
||||
# TODO
|
||||
raise NotImplementedError
|
||||
@@ -45,31 +66,22 @@ def check(context, name):
|
||||
return context
|
||||
|
||||
|
||||
class _TypingBase(object):
|
||||
def __init__(self, typing_context):
|
||||
self._class_context = typing_context
|
||||
class TypingProxy(_TypingBase):
|
||||
py__simple_getitem__ = None
|
||||
|
||||
def __getattr__(self, name):
|
||||
return getattr(self._class_context, name)
|
||||
|
||||
|
||||
class TypingProxy(object):
|
||||
def py__getitem__(self, index_context, contextualized_node):
|
||||
return TypingProxyWithIndex(self._class_context, index_context)
|
||||
|
||||
def __repr__(self):
|
||||
return '%s(%s)' % (self.__class__.__name__, self._class_context)
|
||||
return ContextSet(TypingProxyWithIndex(self._name, self._context, index_context))
|
||||
|
||||
|
||||
class _WithIndexBase(_TypingBase):
|
||||
def __init__(self, class_context, index_context):
|
||||
super(_WithIndexBase, self).__init__(class_context)
|
||||
def __init__(self, name, class_context, index_context):
|
||||
super(_WithIndexBase, self).__init__(name, class_context)
|
||||
self._index_context = index_context
|
||||
|
||||
def __repr__(self):
|
||||
return '%s(%s, %s)' % (
|
||||
self.__class__.__name__,
|
||||
self._class_context,
|
||||
self._context,
|
||||
self._index_context
|
||||
)
|
||||
|
||||
@@ -80,12 +92,8 @@ class _WithIndexBase(_TypingBase):
|
||||
|
||||
|
||||
class TypingProxyWithIndex(_WithIndexBase):
|
||||
def __init__(self, typing_context, index_context):
|
||||
self._class_context = typing_context
|
||||
self._index_context = index_context
|
||||
|
||||
def execute_annotation(self):
|
||||
name = self._class_context.py__name__()
|
||||
name = self._name
|
||||
if name == 'Union':
|
||||
# This is kind of a special case, because we have Unions (in Jedi
|
||||
# ContextSets).
|
||||
@@ -93,17 +101,17 @@ class TypingProxyWithIndex(_WithIndexBase):
|
||||
elif name == 'Optional':
|
||||
# Optional is basically just saying it's either None or the actual
|
||||
# type.
|
||||
return ContextSet(self._class_context) \
|
||||
return ContextSet(self._context) \
|
||||
| ContextSet(builtin_from_name(self.evaluator, u'None'))
|
||||
elif name == 'Type':
|
||||
# The type is actually already given in the index_context
|
||||
return ContextSet(self._index_context)
|
||||
elif name == 'ClassVar':
|
||||
# For now don't do anything here, ClassVars are always used.
|
||||
return self._class_context.execute_annotation()
|
||||
return self._context.execute_annotation()
|
||||
|
||||
cls = globals()[name]
|
||||
return cls(self._class_context, self._index_context)
|
||||
return ContextSet(cls(name, self._context, self._index_context))
|
||||
|
||||
|
||||
def _iter_over_arguments(maybe_tuple_context):
|
||||
@@ -146,14 +154,14 @@ class Tuple(_ContainerBase):
|
||||
return self._get_getitem_contexts(0)
|
||||
else:
|
||||
if isinstance(index, int):
|
||||
return self._get_getitem_contexts(index)
|
||||
return self._get_getitem_contexts(index).execute_annotation()
|
||||
|
||||
debug.dbg('The getitem is')
|
||||
debug.dbg('The getitem type on Tuple was %s' % index)
|
||||
return NO_CONTEXTS
|
||||
|
||||
def py__getitem__(self):
|
||||
if self._is_homogenous():
|
||||
return self._get_getitem_contexts(0)
|
||||
return self._get_getitem_contexts(0).execute_annotation()
|
||||
|
||||
return self._execute_annotations_for_all_indexes()
|
||||
|
||||
|
||||
@@ -21,9 +21,9 @@ from textwrap import dedent
|
||||
from parso import parse, ParserSyntaxError
|
||||
|
||||
from jedi._compatibility import u
|
||||
from jedi import debug
|
||||
from jedi.evaluate.utils import indent_block
|
||||
from jedi.evaluate.cache import evaluator_method_cache
|
||||
from jedi.evaluate.helpers import execute_evaluated
|
||||
from jedi.evaluate.base_context import iterator_to_context_set, ContextSet, \
|
||||
NO_CONTEXTS
|
||||
from jedi.evaluate.lazy_context import LazyKnownContexts
|
||||
@@ -203,6 +203,7 @@ def _evaluate_for_statement_string(module_context, string):
|
||||
# Take the default grammar here, if we load the Python 2.7 grammar here, it
|
||||
# will be impossible to use `...` (Ellipsis) as a token. Docstring types
|
||||
# don't need to conform with the current grammar.
|
||||
debug.dbg('Parse docstring code %s', string, color='BLUE')
|
||||
grammar = module_context.evaluator.latest_grammar
|
||||
try:
|
||||
module = grammar.parse(code.format(indent_block(string)), error_recovery=False)
|
||||
@@ -262,7 +263,7 @@ def _execute_array_values(evaluator, array):
|
||||
values.append(LazyKnownContexts(objects))
|
||||
return {FakeSequence(evaluator, array.array_type, values)}
|
||||
else:
|
||||
return execute_evaluated(array)
|
||||
return array.execute_annotation()
|
||||
|
||||
|
||||
@evaluator_method_cache()
|
||||
@@ -288,6 +289,7 @@ def infer_param(execution_context, param):
|
||||
class_context = execution_context.var_args.instance.class_context
|
||||
types |= eval_docstring(class_context.py__doc__())
|
||||
|
||||
debug.dbg('Found param types for docstring %s', types, color='BLUE')
|
||||
return types
|
||||
|
||||
|
||||
|
||||
@@ -160,6 +160,7 @@ def eval_trailer(context, base_contexts, trailer):
|
||||
# https://github.com/davidhalter/jedi/issues/663
|
||||
result = ContextSet()
|
||||
for typ in list(foo):
|
||||
continue
|
||||
if isinstance(typ, (ClassContext, TreeInstance)):
|
||||
typing_module_types = pep0484.py__simple_getitem__(context, typ, node)
|
||||
if typing_module_types is not None:
|
||||
@@ -678,7 +679,7 @@ def eval_subscript_list(evaluator, context, index):
|
||||
|
||||
return ContextSet(iterable.Slice(context, *result))
|
||||
elif index.type == 'subscriptlist':
|
||||
return NO_CONTEXTS
|
||||
return ContextSet(iterable.SequenceLiteralContext(evaluator, context, index))
|
||||
|
||||
# No slices
|
||||
return context.eval_node(index)
|
||||
|
||||
@@ -35,5 +35,5 @@ class _PluginCallbacks(object):
|
||||
plugin_manager = _PluginManager([
|
||||
StdlibPlugin,
|
||||
FlaskPlugin,
|
||||
#TypeshedPlugin,
|
||||
TypeshedPlugin,
|
||||
])
|
||||
|
||||
@@ -10,6 +10,7 @@ from jedi.evaluate.base_context import ContextSet, iterator_to_context_set
|
||||
from jedi.evaluate.filters import AbstractTreeName, ParserTreeFilter, \
|
||||
TreeNameDefinition
|
||||
from jedi.evaluate.context import ModuleContext, FunctionContext, ClassContext
|
||||
from jedi.evaluate.context.typing import TypingModuleWrapper
|
||||
from jedi.evaluate.compiled import CompiledObject
|
||||
from jedi.evaluate.syntax_tree import tree_name_to_contexts
|
||||
from jedi.evaluate.utils import to_list
|
||||
@@ -133,7 +134,7 @@ class TypeshedPlugin(BasePlugin):
|
||||
)
|
||||
import_name = import_names[-1]
|
||||
map_ = None
|
||||
if len(import_names) == 1 and import_name != 'typing':
|
||||
if len(import_names) == 1:
|
||||
map_ = self._cache_stub_file_map(evaluator.grammar.version_info)
|
||||
elif isinstance(parent_module_context, StubModuleContext):
|
||||
map_ = _merge_create_stub_map(parent_module_context.py__path__())
|
||||
@@ -152,9 +153,10 @@ class TypeshedPlugin(BasePlugin):
|
||||
stub_module_context = StubOnlyModuleContext(
|
||||
context_set, evaluator, stub_module_node, path, code_lines=[]
|
||||
)
|
||||
return ContextSet.from_iterable(
|
||||
_merge_modules(context_set, stub_module_context)
|
||||
)
|
||||
modules = _merge_modules(context_set, stub_module_context)
|
||||
if import_names == ('typing',):
|
||||
modules = [TypingModuleWrapper('typing', m) for m in modules]
|
||||
return ContextSet.from_iterable(modules)
|
||||
# If no stub is found, just return the default.
|
||||
return context_set
|
||||
return wrapper
|
||||
|
||||
Reference in New Issue
Block a user