mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-07 06:24:27 +08:00
Add testing for mismatch cases
This should help catch any errors in our handling of invalid cases. While some of these produce outputs which aren't correct, what we're checking here is that we don't _error_ while producing that output. Also fix a case which this showed up.
This commit is contained in:
@@ -494,6 +494,11 @@ def _infer_type_vars(annotation_value, value_set, is_class_value=False):
|
||||
# the elements from the set first, then handle them, even if we put
|
||||
# them back in a set afterwards.
|
||||
for element in value_set:
|
||||
if element.api_type == u'function':
|
||||
# Functions & methods don't have an MRO and we're not
|
||||
# expecting a Callable (those are handled separately above).
|
||||
continue
|
||||
|
||||
if element.is_instance():
|
||||
py_class = element.get_annotated_class_object()
|
||||
else:
|
||||
|
||||
320
test/completion/pep0484_generic_mismatches.py
Normal file
320
test/completion/pep0484_generic_mismatches.py
Normal file
@@ -0,0 +1,320 @@
|
||||
# python >= 3.4
|
||||
from typing import (
|
||||
Callable,
|
||||
Dict,
|
||||
Generic,
|
||||
List,
|
||||
Sequence,
|
||||
Tuple,
|
||||
Type,
|
||||
TypeVar,
|
||||
)
|
||||
|
||||
T = TypeVar('T')
|
||||
|
||||
|
||||
def foo(x: T) -> T:
|
||||
return x
|
||||
|
||||
|
||||
class CustomGeneric(Generic[T]):
|
||||
def __init__(self, val: T) -> None:
|
||||
self.val = val
|
||||
|
||||
|
||||
class PlainClass(object):
|
||||
pass
|
||||
|
||||
|
||||
tpl = ("1", 2)
|
||||
tpl_typed = ("2", 3) # type: Tuple[str, int]
|
||||
|
||||
collection = {"a": 1}
|
||||
collection_typed = {"a": 1} # type: Dict[str, int]
|
||||
|
||||
list_of_funcs = [foo] # type: List[Callable[[T], T]]
|
||||
|
||||
custom_generic = CustomGeneric(123.45)
|
||||
|
||||
plain_instance = PlainClass()
|
||||
|
||||
|
||||
# Test that simple parameters are handled
|
||||
def list_t_to_list_t(the_list: List[T]) -> List[T]:
|
||||
return the_list
|
||||
|
||||
x0 = list_t_to_list_t("abc")[0]
|
||||
#?
|
||||
x0
|
||||
|
||||
x1 = list_t_to_list_t(foo)[0]
|
||||
#?
|
||||
x1
|
||||
|
||||
x2 = list_t_to_list_t(tpl)[0]
|
||||
#?
|
||||
x2
|
||||
|
||||
x3 = list_t_to_list_t(tpl_typed)[0]
|
||||
#?
|
||||
x3
|
||||
|
||||
x4 = list_t_to_list_t(collection)[0]
|
||||
#?
|
||||
x4
|
||||
|
||||
x5 = list_t_to_list_t(collection_typed)[0]
|
||||
#?
|
||||
x5
|
||||
|
||||
x6 = list_t_to_list_t(custom_generic)[0]
|
||||
#?
|
||||
x6
|
||||
|
||||
x7 = list_t_to_list_t(plain_instance)[0]
|
||||
#?
|
||||
x7
|
||||
|
||||
for a in list_t_to_list_t(12):
|
||||
#?
|
||||
a
|
||||
|
||||
|
||||
# Test that simple parameters are handled
|
||||
def list_type_t_to_list_t(the_list: List[Type[T]]) -> List[T]:
|
||||
return [x() for x in the_list]
|
||||
|
||||
x0 = list_type_t_to_list_t("abc")[0]
|
||||
#?
|
||||
x0
|
||||
|
||||
x1 = list_type_t_to_list_t(foo)[0]
|
||||
#?
|
||||
x1
|
||||
|
||||
x2 = list_type_t_to_list_t(tpl)[0]
|
||||
#?
|
||||
x2
|
||||
|
||||
x3 = list_type_t_to_list_t(tpl_typed)[0]
|
||||
#?
|
||||
x3
|
||||
|
||||
x4 = list_type_t_to_list_t(collection)[0]
|
||||
#?
|
||||
x4
|
||||
|
||||
x5 = list_type_t_to_list_t(collection_typed)[0]
|
||||
#?
|
||||
x5
|
||||
|
||||
x6 = list_type_t_to_list_t(custom_generic)[0]
|
||||
#?
|
||||
x6
|
||||
|
||||
x7 = list_type_t_to_list_t(plain_instance)[0]
|
||||
#?
|
||||
x7
|
||||
|
||||
for a in list_type_t_to_list_t(12):
|
||||
#?
|
||||
a
|
||||
|
||||
|
||||
x0 = list_type_t_to_list_t(["abc"])[0]
|
||||
#?
|
||||
x0
|
||||
|
||||
x1 = list_type_t_to_list_t([foo])[0]
|
||||
#?
|
||||
x1
|
||||
|
||||
x2 = list_type_t_to_list_t([tpl])[0]
|
||||
#?
|
||||
x2
|
||||
|
||||
x3 = list_type_t_to_list_t([tpl_typed])[0]
|
||||
#?
|
||||
x3
|
||||
|
||||
x4 = list_type_t_to_list_t([collection])[0]
|
||||
#?
|
||||
x4
|
||||
|
||||
x5 = list_type_t_to_list_t([collection_typed])[0]
|
||||
#?
|
||||
x5
|
||||
|
||||
x6 = list_type_t_to_list_t([custom_generic])[0]
|
||||
#?
|
||||
x6
|
||||
|
||||
x7 = list_type_t_to_list_t([plain_instance])[0]
|
||||
#?
|
||||
x7
|
||||
|
||||
for a in list_type_t_to_list_t([12]):
|
||||
#?
|
||||
a
|
||||
|
||||
|
||||
def list_func_t_to_list_t(the_list: List[Callable[[T], T]]) -> List[T]:
|
||||
# Not actually a viable signature, but should be enough to test our handling
|
||||
# of the generic parameters.
|
||||
pass
|
||||
|
||||
|
||||
x0 = list_func_t_to_list_t("abc")[0]
|
||||
#?
|
||||
x0
|
||||
|
||||
x1 = list_func_t_to_list_t(foo)[0]
|
||||
#?
|
||||
x1
|
||||
|
||||
x2 = list_func_t_to_list_t(tpl)[0]
|
||||
#?
|
||||
x2
|
||||
|
||||
x3 = list_func_t_to_list_t(tpl_typed)[0]
|
||||
#?
|
||||
x3
|
||||
|
||||
x4 = list_func_t_to_list_t(collection)[0]
|
||||
#?
|
||||
x4
|
||||
|
||||
x5 = list_func_t_to_list_t(collection_typed)[0]
|
||||
#?
|
||||
x5
|
||||
|
||||
x6 = list_func_t_to_list_t(custom_generic)[0]
|
||||
#?
|
||||
x6
|
||||
|
||||
x7 = list_func_t_to_list_t(plain_instance)[0]
|
||||
#?
|
||||
x7
|
||||
|
||||
for a in list_func_t_to_list_t(12):
|
||||
#?
|
||||
a
|
||||
|
||||
|
||||
# The following are all actually wrong, however we're mainly testing here that
|
||||
# we don't error when processing invalid values, rather than that we get the
|
||||
# right output.
|
||||
|
||||
x0 = list_func_t_to_list_t(["abc"])[0]
|
||||
#? str()
|
||||
x0
|
||||
|
||||
x2 = list_func_t_to_list_t([tpl])[0]
|
||||
#? tuple()
|
||||
x2
|
||||
|
||||
x3 = list_func_t_to_list_t([tpl_typed])[0]
|
||||
#? tuple()
|
||||
x3
|
||||
|
||||
x4 = list_func_t_to_list_t([collection])[0]
|
||||
#? dict()
|
||||
x4
|
||||
|
||||
x5 = list_func_t_to_list_t([collection_typed])[0]
|
||||
#? dict()
|
||||
x5
|
||||
|
||||
x6 = list_func_t_to_list_t([custom_generic])[0]
|
||||
#? CustomGeneric()
|
||||
x6
|
||||
|
||||
x7 = list_func_t_to_list_t([plain_instance])[0]
|
||||
#? PlainClass()
|
||||
x7
|
||||
|
||||
for a in list_func_t_to_list_t([12]):
|
||||
#? int()
|
||||
a
|
||||
|
||||
|
||||
def tuple_t(tuple_in: Tuple[T]]) -> Sequence[T]:
|
||||
return tuple_in
|
||||
|
||||
|
||||
x0 = list_t_to_list_t("abc")[0]
|
||||
#?
|
||||
x0
|
||||
|
||||
x1 = list_t_to_list_t(foo)[0]
|
||||
#?
|
||||
x1
|
||||
|
||||
x2 = list_t_to_list_t(tpl)[0]
|
||||
#?
|
||||
x2
|
||||
|
||||
x3 = list_t_to_list_t(tpl_typed)[0]
|
||||
#?
|
||||
x3
|
||||
|
||||
x4 = list_t_to_list_t(collection)[0]
|
||||
#?
|
||||
x4
|
||||
|
||||
x5 = list_t_to_list_t(collection_typed)[0]
|
||||
#?
|
||||
x5
|
||||
|
||||
x6 = list_t_to_list_t(custom_generic)[0]
|
||||
#?
|
||||
x6
|
||||
|
||||
x7 = list_t_to_list_t(plain_instance)[0]
|
||||
#?
|
||||
x7
|
||||
|
||||
for a in list_t_to_list_t(12):
|
||||
#?
|
||||
a
|
||||
|
||||
|
||||
def tuple_t_elipsis(tuple_in: Tuple[T, ...]]) -> Sequence[T]:
|
||||
return tuple_in
|
||||
|
||||
|
||||
x0 = list_t_to_list_t("abc")[0]
|
||||
#?
|
||||
x0
|
||||
|
||||
x1 = list_t_to_list_t(foo)[0]
|
||||
#?
|
||||
x1
|
||||
|
||||
x2 = list_t_to_list_t(tpl)[0]
|
||||
#?
|
||||
x2
|
||||
|
||||
x3 = list_t_to_list_t(tpl_typed)[0]
|
||||
#?
|
||||
x3
|
||||
|
||||
x4 = list_t_to_list_t(collection)[0]
|
||||
#?
|
||||
x4
|
||||
|
||||
x5 = list_t_to_list_t(collection_typed)[0]
|
||||
#?
|
||||
x5
|
||||
|
||||
x6 = list_t_to_list_t(custom_generic)[0]
|
||||
#?
|
||||
x6
|
||||
|
||||
x7 = list_t_to_list_t(plain_instance)[0]
|
||||
#?
|
||||
x7
|
||||
|
||||
for a in list_t_to_list_t(12):
|
||||
#?
|
||||
a
|
||||
@@ -342,6 +342,7 @@ def test_file_fuzzy_completion(Script):
|
||||
script = Script('"{}/ep08_i'.format(path))
|
||||
expected = [
|
||||
'pep0484_basic.py"',
|
||||
'pep0484_generic_mismatches.py"',
|
||||
'pep0484_generic_parameters.py"',
|
||||
'pep0484_generic_passthroughs.py"',
|
||||
'pep0484_typing.py"',
|
||||
|
||||
Reference in New Issue
Block a user