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

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

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]

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

View File

@@ -69,5 +69,90 @@ def sets(
#? ["add"]
q.a
def tuple(
p: typing.Tuple[int],
q: typing.Tuple[int, str, float],
r: typing.Tuple[B, ...]):
#? int()
p[0]
#? int()
q[0]
#? str()
q[1]
#? float()
q[2]
#? B()
r[0]
##? B() --- TODO fix support for arbitrary length
r[1]
#? B()
r[2]
#? B()
r[10000]
i, s, f = q
#? int()
i
##? str() --- TODO fix support for tuple assignment
s
##? float() --- TODO fix support for tuple assignment
f
class Key:
pass
class Value:
pass
def mapping(
p: typing.Mapping[Key, Value],
q: typing.MutableMapping[Key, Value],
d: typing.Dict[Key, Value],
r: typing.KeysView[Key],
s: typing.ValuesView[Value],
t: typing.ItemsView[Key, Value]):
#? []
p.setd
#? ["setdefault"]
q.setd
#? ["setdefault"]
d.setd
#? Value()
p[1]
for key in p:
#? Key()
key
for key in p.keys():
#? Key()
key
for value in p.values():
#? Value()
value
for item in p.items():
#? Key()
item[0]
#? Value()
item[1]
(key, value) = item
#? Key()
key
##? Value() --- TODO fix support for tuple assignment
value
for key, value in p.items():
#? Key()
key
##? Value() --- TODO fix support for tuple assignment
value
for key in r:
#? Key()
key
for value in s:
#? Value()
value
for key, value in t:
#? Key()
key
##? Value() --- TODO fix support for tuple assignment
value
class ForwardReference:
pass