mirror of
https://github.com/davidhalter/jedi.git
synced 2026-01-31 10:15:23 +08:00
tuples and mappings in typing
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user