forked from VimPlug/jedi
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
|
from jedi.evaluate.representation import Class
|
||||||
result = set()
|
result = set()
|
||||||
|
|
||||||
|
trailer_op, node, trailer_cl = trailer.children
|
||||||
|
assert trailer_op == "["
|
||||||
|
assert trailer_cl == "]"
|
||||||
|
|
||||||
# special case: PEP0484 typing module, see
|
# special case: PEP0484 typing module, see
|
||||||
# https://github.com/davidhalter/jedi/issues/663
|
# https://github.com/davidhalter/jedi/issues/663
|
||||||
for typ in list(types):
|
for typ in list(types):
|
||||||
if isinstance(typ, Class):
|
if isinstance(typ, Class):
|
||||||
typing_module_types = \
|
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:
|
if typing_module_types is not None:
|
||||||
types.remove(typ)
|
types.remove(typ)
|
||||||
result |= typing_module_types
|
result |= typing_module_types
|
||||||
@@ -579,12 +582,6 @@ def py__getitem__(evaluator, types, trailer):
|
|||||||
# all consumed by special cases
|
# all consumed by special cases
|
||||||
return result
|
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):
|
for index in create_index_types(evaluator, node):
|
||||||
if isinstance(index, (compiled.CompiledObject, Slice)):
|
if isinstance(index, (compiled.CompiledObject, Slice)):
|
||||||
index = index.obj
|
index = index.obj
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ except ImportError:
|
|||||||
import collections as abc
|
import collections as abc
|
||||||
|
|
||||||
|
|
||||||
def factory(typing_name, indextype):
|
def factory(typing_name, indextypes):
|
||||||
class Iterable(abc.Iterable):
|
class Iterable(abc.Iterable):
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
yield indextype()
|
yield indextypes[0]()
|
||||||
|
|
||||||
class Iterator(Iterable, abc.Iterator):
|
class Iterator(Iterable, abc.Iterator):
|
||||||
def next(self):
|
def next(self):
|
||||||
@@ -21,11 +21,11 @@ def factory(typing_name, indextype):
|
|||||||
return self.__next__()
|
return self.__next__()
|
||||||
|
|
||||||
def __next__(self):
|
def __next__(self):
|
||||||
return indextype()
|
return indextypes[0]()
|
||||||
|
|
||||||
class Sequence(Iterable, abc.Sequence):
|
class Sequence(Iterable, abc.Sequence):
|
||||||
def __getitem__(self, index):
|
def __getitem__(self, index):
|
||||||
return indextype()
|
return indextypes[0]()
|
||||||
|
|
||||||
class MutableSequence(Sequence, abc.MutableSequence):
|
class MutableSequence(Sequence, abc.MutableSequence):
|
||||||
pass
|
pass
|
||||||
@@ -33,12 +33,46 @@ def factory(typing_name, indextype):
|
|||||||
class List(MutableSequence, list):
|
class List(MutableSequence, list):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
class Tuple(Sequence, tuple):
|
||||||
|
def __getitem__(self, index):
|
||||||
|
return indextypes[index]()
|
||||||
|
|
||||||
class AbstractSet(Iterable, abc.Set):
|
class AbstractSet(Iterable, abc.Set):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class MutableSet(AbstractSet, abc.MutableSet):
|
class MutableSet(AbstractSet, abc.MutableSet):
|
||||||
pass
|
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 = {
|
dct = {
|
||||||
"Sequence": Sequence,
|
"Sequence": Sequence,
|
||||||
"MutableSequence": MutableSequence,
|
"MutableSequence": MutableSequence,
|
||||||
@@ -47,5 +81,12 @@ def factory(typing_name, indextype):
|
|||||||
"Iterator": Iterator,
|
"Iterator": Iterator,
|
||||||
"AbstractSet": AbstractSet,
|
"AbstractSet": AbstractSet,
|
||||||
"MutableSet": MutableSet,
|
"MutableSet": MutableSet,
|
||||||
|
"Mapping": Mapping,
|
||||||
|
"MutableMapping": MutableMapping,
|
||||||
|
"Tuple": Tuple,
|
||||||
|
"KeysView": KeysView,
|
||||||
|
"ItemsView": ItemsView,
|
||||||
|
"ValuesView": ValuesView,
|
||||||
|
"Dict": Dict,
|
||||||
}
|
}
|
||||||
return dct[typing_name]
|
return dct[typing_name]
|
||||||
|
|||||||
+33
-10
@@ -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
|
Guido https://github.com/davidhalter/jedi/issues/662
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from itertools import chain
|
import itertools
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from jedi.parser import \
|
from jedi.parser import \
|
||||||
@@ -32,7 +32,7 @@ def _evaluate_for_annotation(evaluator, annotation):
|
|||||||
if annotation is not None:
|
if annotation is not None:
|
||||||
dereferenced_annotation = _fix_forward_reference(evaluator, annotation)
|
dereferenced_annotation = _fix_forward_reference(evaluator, annotation)
|
||||||
definitions = evaluator.eval_element(dereferenced_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))
|
evaluator.execute(d) for d in definitions))
|
||||||
else:
|
else:
|
||||||
return []
|
return []
|
||||||
@@ -97,7 +97,8 @@ def _get_typing_replacement_module():
|
|||||||
return p.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":
|
if not typ.base.get_parent_until().name.value == "typing":
|
||||||
return None
|
return None
|
||||||
# we assume that any class using [] in a module called
|
# 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%
|
# should be replaced by that class. This is not 100%
|
||||||
# airtight but I don't have a better idea to check that it's
|
# airtight but I don't have a better idea to check that it's
|
||||||
# actually the PEP-0484 typing module and not some other
|
# actually the PEP-0484 typing module and not some other
|
||||||
indextypes = evaluator.eval_element(trailer.children[1])
|
if tree.is_node(node, "subscriptlist"):
|
||||||
if not isinstance(indextypes, set):
|
nodes = node.children[::2] # skip the commas
|
||||||
indextypes = set([indextypes])
|
else:
|
||||||
|
nodes = [node]
|
||||||
|
|
||||||
typing = _get_typing_replacement_module()
|
typing = _get_typing_replacement_module()
|
||||||
factories = evaluator.find_types(typing, "factory")
|
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)
|
compiled_classname = compiled.create(evaluator, typ.name.value)
|
||||||
|
|
||||||
result = set()
|
result = set()
|
||||||
for indextyp in indextypes:
|
# don't know what the last parameter is for, this seems to work :)
|
||||||
result |= \
|
args = FakeSequence(evaluator, nodes, "x-type")
|
||||||
evaluator.execute_evaluated(factory, compiled_classname, indextyp)
|
|
||||||
|
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:
|
for singleresult in result:
|
||||||
singleresult.name.value += "[%s]" % indextyp.name
|
singleresult.name.value += "[%s]" % ", ".join(human_nodes)
|
||||||
return result
|
return result
|
||||||
|
|||||||
@@ -69,5 +69,90 @@ def sets(
|
|||||||
#? ["add"]
|
#? ["add"]
|
||||||
q.a
|
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:
|
class ForwardReference:
|
||||||
pass
|
pass
|
||||||
|
|||||||
Reference in New Issue
Block a user