1
0
forked from VimPlug/jedi

tuples and mappings in typing

This commit is contained in:
Claude
2015-12-31 01:29:03 +01:00
parent 10f5e15325
commit 7b97312509
4 changed files with 167 additions and 21 deletions
+4 -7
View File
@@ -564,13 +564,16 @@ def py__getitem__(evaluator, types, trailer):
from jedi.evaluate.representation import Class
result = set()
trailer_op, node, trailer_cl = trailer.children
assert trailer_op == "["
assert trailer_cl == "]"
# special case: PEP0484 typing module, see
# https://github.com/davidhalter/jedi/issues/663
for typ in list(types):
if isinstance(typ, Class):
typing_module_types = \
pep0484.get_types_for_typing_module(evaluator, typ, trailer)
pep0484.get_types_for_typing_module(evaluator, typ, node)
if typing_module_types is not None:
types.remove(typ)
result |= typing_module_types
@@ -579,12 +582,6 @@ def py__getitem__(evaluator, types, trailer):
# all consumed by special cases
return result
trailer_op, node, trailer_cl = trailer.children[:3]
assert trailer_op == "["
if trailer_cl != "]":
debug.warning("No support for complex indices: %s" % trailer)
return result
for index in create_index_types(evaluator, node):
if isinstance(index, (compiled.CompiledObject, Slice)):
index = index.obj
+45 -4
View File
@@ -10,10 +10,10 @@ except ImportError:
import collections as abc
def factory(typing_name, indextype):
def factory(typing_name, indextypes):
class Iterable(abc.Iterable):
def __iter__(self):
yield indextype()
yield indextypes[0]()
class Iterator(Iterable, abc.Iterator):
def next(self):
@@ -21,11 +21,11 @@ def factory(typing_name, indextype):
return self.__next__()
def __next__(self):
return indextype()
return indextypes[0]()
class Sequence(Iterable, abc.Sequence):
def __getitem__(self, index):
return indextype()
return indextypes[0]()
class MutableSequence(Sequence, abc.MutableSequence):
pass
@@ -33,12 +33,46 @@ def factory(typing_name, indextype):
class List(MutableSequence, list):
pass
class Tuple(Sequence, tuple):
def __getitem__(self, index):
return indextypes[index]()
class AbstractSet(Iterable, abc.Set):
pass
class MutableSet(AbstractSet, abc.MutableSet):
pass
class KeysView(Iterable, abc.KeysView):
pass
class ValuesView(abc.ValuesView):
def __iter__(self):
yield indextypes[1]()
class ItemsView(abc.ItemsView):
def __iter__(self):
yield Tuple()
class Mapping(Iterable, abc.Mapping):
def __getitem__(self, item):
return indextypes[1]()
def keys(self):
return KeysView()
def values(self):
return ValuesView()
def items(self):
return ItemsView()
class MutableMapping(Mapping, abc.MutableMapping):
pass
class Dict(MutableMapping, dict):
pass
dct = {
"Sequence": Sequence,
"MutableSequence": MutableSequence,
@@ -47,5 +81,12 @@ def factory(typing_name, indextype):
"Iterator": Iterator,
"AbstractSet": AbstractSet,
"MutableSet": MutableSet,
"Mapping": Mapping,
"MutableMapping": MutableMapping,
"Tuple": Tuple,
"KeysView": KeysView,
"ItemsView": ItemsView,
"ValuesView": ValuesView,
"Dict": Dict,
}
return dct[typing_name]
+33 -10
View File
@@ -18,7 +18,7 @@ x support for type hint comments `# type: (int, str) -> int`. See comment from
Guido https://github.com/davidhalter/jedi/issues/662
"""
from itertools import chain
import itertools
import os
from jedi.parser import \
@@ -32,7 +32,7 @@ def _evaluate_for_annotation(evaluator, annotation):
if annotation is not None:
dereferenced_annotation = _fix_forward_reference(evaluator, annotation)
definitions = evaluator.eval_element(dereferenced_annotation)
return list(chain.from_iterable(
return list(itertools.chain.from_iterable(
evaluator.execute(d) for d in definitions))
else:
return []
@@ -97,7 +97,8 @@ def _get_typing_replacement_module():
return p.module
def get_types_for_typing_module(evaluator, typ, trailer):
def get_types_for_typing_module(evaluator, typ, node):
from jedi.evaluate.iterable import FakeSequence
if not typ.base.get_parent_until().name.value == "typing":
return None
# we assume that any class using [] in a module called
@@ -105,9 +106,10 @@ def get_types_for_typing_module(evaluator, typ, trailer):
# should be replaced by that class. This is not 100%
# airtight but I don't have a better idea to check that it's
# actually the PEP-0484 typing module and not some other
indextypes = evaluator.eval_element(trailer.children[1])
if not isinstance(indextypes, set):
indextypes = set([indextypes])
if tree.is_node(node, "subscriptlist"):
nodes = node.children[::2] # skip the commas
else:
nodes = [node]
typing = _get_typing_replacement_module()
factories = evaluator.find_types(typing, "factory")
@@ -123,9 +125,30 @@ def get_types_for_typing_module(evaluator, typ, trailer):
compiled_classname = compiled.create(evaluator, typ.name.value)
result = set()
for indextyp in indextypes:
result |= \
evaluator.execute_evaluated(factory, compiled_classname, indextyp)
# don't know what the last parameter is for, this seems to work :)
args = FakeSequence(evaluator, nodes, "x-type")
result |= evaluator.execute_evaluated(factory, compiled_classname, args)
human_nodes = []
for node in nodes:
evalled_node = evaluator.eval_element(node)
if len(evalled_node) != 1:
human_nodes.append("???")
continue
evalled_node = list(evalled_node)[0]
try:
human_nodes.append(str(evalled_node.name))
except AttributeError:
pass
else:
continue
try:
human_nodes.append(evalled_node.obj.__name__)
except AttributeError:
pass
else:
continue
human_nodes.append("???")
for singleresult in result:
singleresult.name.value += "[%s]" % indextyp.name
singleresult.name.value += "[%s]" % ", ".join(human_nodes)
return result