Skip to content

Commit 58c2e23

Browse files
committed
Disallow type applications
For example, x = List[int]() is no longer supported (to conform to PEP 484). Usually, a '# type:' comment or a cast can be used instead. Closes #556.
1 parent b9056a2 commit 58c2e23

8 files changed

+81
-279
lines changed

mypy/checkexpr.py

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -988,22 +988,8 @@ def is_valid_cast(self, source_type: Type, target_type: Type) -> bool:
988988

989989
def visit_type_application(self, tapp: TypeApplication) -> Type:
990990
"""Type check a type application (expr[type, ...])."""
991-
expr_type = self.accept(tapp.expr)
992-
if isinstance(expr_type, CallableType):
993-
new_type = self.apply_generic_arguments(expr_type,
994-
tapp.types, tapp)
995-
elif isinstance(expr_type, Overloaded):
996-
overload = expr_type
997-
# Only target items with the right number of generic type args.
998-
items = [c for c in overload.items()
999-
if len(c.variables) == len(tapp.types)]
1000-
new_type = self.apply_generic_arguments2(Overloaded(items),
1001-
tapp.types, tapp)
1002-
else:
1003-
self.chk.fail(messages.INVALID_TYPE_APPLICATION_TARGET_TYPE, tapp)
1004-
new_type = AnyType()
1005-
self.chk.type_map[tapp.expr] = new_type
1006-
return new_type
991+
self.chk.fail(messages.GENERIC_TYPE_NOT_VALID_AS_EXPRESSION, tapp)
992+
return AnyType()
1007993

1008994
def visit_type_alias_expr(self, alias: TypeAliasExpr) -> Type:
1009995
return AnyType()

mypy/messages.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@
6464
'Overloaded method has both abstract and non-abstract variants'
6565
INSTANCE_LAYOUT_CONFLICT = 'Instance layout conflict in multiple inheritance'
6666
FORMAT_REQUIRES_MAPPING = 'Format requires a mapping'
67+
GENERIC_TYPE_NOT_VALID_AS_EXPRESSION = \
68+
"Generic type not valid as an expression any more (use '# type:' comment instead)"
69+
6770

6871
class MessageBuilder:
6972
"""Helper class for reporting type checker error messages with parameters.

mypy/test/data/check-generics.test

Lines changed: 42 additions & 192 deletions
Original file line numberDiff line numberDiff line change
@@ -375,99 +375,8 @@ main, line 9: Incompatible types in assignment (expression has type A[A[B]], var
375375
-- -----------------
376376

377377

378-
[case testTrivialTypeApplication]
379-
from typing import TypeVar
380-
T = TypeVar('T')
381-
def f(x: T) -> None: pass
382-
f[object](None)
383-
[out]
384-
385-
[case testSimpleGenericFunction]
386-
from typing import Undefined, TypeVar
387-
T = TypeVar('T')
388-
class A: pass
389-
class B: pass
390-
a = Undefined # type: A
391-
b = Undefined # type: B
392-
393-
def id(a: T) -> T:
394-
return a
395-
396-
b = id[B](a) # E: Argument 1 to "id" has incompatible type "A"; expected "B"
397-
a = id[B](b) # E: Incompatible types in assignment (expression has type "B", variable has type "A")
398-
a = id[A](a)
399-
400-
[case testGenericFunctionWithTwoTypeArguments]
401-
from typing import Undefined, TypeVar, Generic
402-
S = TypeVar('S')
403-
T = TypeVar('T')
404-
405-
class t(Generic[S, T]): pass
406-
class B: pass
407-
class C: pass
408-
409-
tbc = Undefined # type: t[B, C]
410-
tbb = Undefined # type: t[B, B]
411-
b = Undefined # type: B
412-
c = Undefined # type: C
413-
414-
def f(a: S, b: t[S, T]) -> t[S, T]: pass
415-
416-
tbc = f[B, C](c, tbc) # E: Argument 1 to "f" has incompatible type "C"; expected "B"
417-
tbc = f[B, C](b, tbb) # E: Argument 2 to "f" has incompatible type t[B, B]; expected t[B, C]
418-
tbb = f[B, C](b, tbc) # E: Incompatible types in assignment (expression has type t[B, C], variable has type t[B, B])
419-
tbc = f[B, C](b, tbc)
420-
421-
[case testInvalidNumberOfTypeArgumentsForGenericFunction]
422-
from typing import Undefined, TypeVar, Generic
423-
s = TypeVar('s')
424-
t = TypeVar('t')
425-
class p(Generic[s, t]): pass
426-
def f(a: p[s, t]) -> None: pass
427-
def g() -> None: pass
428-
a = Undefined # type: p[object, object]
429-
430-
a = f[object](a) # E: Type application has too few types (2 expected)
431-
a = f[object, object, object](a) # E: Type application has too many types (2 expected)
432-
g[object]() # E: Type application targets a non-generic function
433-
f[object, object](a)
434-
435-
-- NOTE: Commented out test cases that do not make sense currently.
436-
437-
--[case testGenericMethodInNonGenericType]
438-
--from typing import Undefined, TypeVar
439-
--T = TypeVar('T')
440-
--a, b = Undefined, Undefined # type: (A, B)
441-
--class A:
442-
-- def f(self, a: T) -> T: pass
443-
--class B: pass
444-
--
445-
--a = a.f[B](b) # E: Incompatible types in assignment
446-
--a = a.f[A](b) # E: Argument 1 to "f" of "A" has incompatible type "B"
447-
--a = a.f[A](a)
448-
449-
--[case testGenericMethodInGenericType]
450-
--from typing import Undefined, TypeVar, Generic
451-
--T = TypeVar('T')
452-
--S = TypeVar('S')
453-
--class A(Generic[T]):
454-
-- def f(self, a: S) -> 'A[t[S, T]]':
455-
-- pass
456-
--class t(Generic[T, S]): pass
457-
--class B: pass
458-
--class C: pass
459-
--ab = Undefined # type: A[B]
460-
--acb = Undefined # type: A[t[C, B]]
461-
--abc = Undefined # type: A[t[B, C]]
462-
--b = Undefined # type: B
463-
--c = Undefined # type: C
464-
--
465-
--abc = ab.f[C](c) # E: Incompatible types in assignment
466-
--acb = ab.f[C](b) # E: Argument 1 to "f" of "A" has incompatible type "B"
467-
--acb = ab.f[C](c)
468-
469378
[case testTypeCheckingGenericFunctionBody]
470-
from typing import TypeVar, Generic
379+
from typing import TypeVar, Generic, Undefined
471380
S = TypeVar('S')
472381
T = TypeVar('T')
473382
class A: pass
@@ -476,118 +385,69 @@ class p(Generic[T, S]):
476385
def f(s: S, t: T) -> p[T, A]:
477386
a = t # type: S # E: Incompatible types in assignment (expression has type "T", variable has type "S")
478387
s = t # E: Incompatible types in assignment (expression has type "T", variable has type "S")
479-
return p[S, A](s, A()) # E: Incompatible return value type: expected __main__.p[T`-2, __main__.A], got __main__.p[S`-1, __main__.A*]
388+
p_s_a = Undefined(p[S, A])
389+
if s:
390+
return p_s_a # E: Incompatible return value type: expected __main__.p[T`-2, __main__.A], got __main__.p[S`-1, __main__.A]
480391
b = t # type: T
481392
c = s # type: S
482-
return p[T, A](t, A())
393+
p_t_a = Undefined(p[T, A])
394+
return p_t_a
483395
[out]
484396
main: In function "f":
485397

486398
[case testTypeCheckingGenericMethodBody]
487-
from typing import TypeVar, Generic
399+
from typing import TypeVar, Generic, Undefined
488400
T = TypeVar('T')
489401
S = TypeVar('S')
490402
class p(Generic[T, S]):
491403
def __init__(self, t: T, a: S) -> None: pass
492404
class A(Generic[T]):
493405
def f(self, s: S, t: T) -> p[S, T]:
494406
s = t # E: Incompatible types in assignment (expression has type "T", variable has type "S")
495-
return p[S, S](s, s) # E: Incompatible return value type: expected __main__.p[S`-1, T`1], got __main__.p[S`-1, S`-1]
496-
return p[T, T](t, t) # E: Incompatible return value type: expected __main__.p[S`-1, T`1], got __main__.p[T`1, T`1]
407+
p_s_s = Undefined(p[S, S])
408+
if s:
409+
return p_s_s # E: Incompatible return value type: expected __main__.p[S`-1, T`1], got __main__.p[S`-1, S`-1]
410+
p_t_t = Undefined(p[T, T])
411+
if s:
412+
return p_t_t # E: Incompatible return value type: expected __main__.p[S`-1, T`1], got __main__.p[T`1, T`1]
497413
t = t
498414
s = s
499-
return p[S, T](s, t)
415+
p_s_t = Undefined(p[S, T])
416+
return p_s_t
500417
[out]
501418
main: In member "f" of class "A":
502419

503420

504-
-- Constructing instances + generics
505-
-- ---------------------------------
421+
-- Generic types in expressions
422+
-- ----------------------------
506423

507424

508-
[case testConstructingGenericInstanceWithEmptyConstructor]
425+
[case testInvalidTypeApplicationTarget]
509426
from typing import TypeVar, Generic
510427
T = TypeVar('T')
511428
class A(Generic[T]): pass
512-
class B: pass
513-
class C: pass
514-
a = A[B]() # type: A[C] # Fail
515-
a = A[B]() # Fail
516-
e = A[B]() # type: A[B]
517-
e = A[B]()
429+
A[A]() # E: Generic type not valid as an expression any more (use '# type:' comment instead)
430+
A[int, str]() # E: Generic type not valid as an expression any more (use '# type:' comment instead)
518431
[out]
519-
main, line 6: Incompatible types in assignment (expression has type A[B], variable has type A[C])
520-
main, line 7: Incompatible types in assignment (expression has type A[B], variable has type A[C])
521432

522-
[case testNonEmptyGenericTypeConstructor]
523-
from typing import Undefined, TypeVar, Generic
433+
[case testInvalidTypeApplicationTarget2]
434+
from typing import TypeVar, Generic
524435
T = TypeVar('T')
525-
class B: pass
526-
class C: pass
527-
class A(Generic[T]):
528-
def __init__(self, a: T, b: B) -> None: pass
529-
ac = Undefined # type: A[C]
530-
ab = Undefined # type: A[B]
531-
b = Undefined # type: B
532-
c = Undefined # type: C
533-
534-
ac = A[C](b, b) # E: Argument 1 to "A" has incompatible type "B"; expected "C"
535-
ab = A[C](c, b) # E: Incompatible types in assignment (expression has type A[C], variable has type A[B])
536-
ac = A[C](c, b)
537-
538-
[case testConstructorForGenericTypeWithMultipleArguments]
539-
from typing import Undefined, TypeVar, Generic
540436
S = TypeVar('S')
541-
T = TypeVar('T')
542-
class A(Generic[S, T]):
543-
def __init__(self, t: T, s: S) -> None: pass
544-
class B: pass
545-
class C: pass
546-
547-
abc = Undefined # type: A[B, C]
548-
acb = Undefined # type: A[C, B]
549-
b, c = Undefined, Undefined # type: (B, C)
550-
551-
abc = A[B, C](b, b) # E: Argument 1 to "A" has incompatible type "B"; expected "C"
552-
abc = A[B, C](c, c) # E: Argument 2 to "A" has incompatible type "C"; expected "B"
553-
acb = A[B, C](c, b) # E: Incompatible types in assignment (expression has type A[B, C], variable has type A[C, B])
554-
abc = A[B, C](c, b)
555-
acb = A[C, B](b, c)
556-
557-
[case testGenericConstructorOfNonGenericType]
558-
from typing import Undefined, TypeVar
559-
T = TypeVar('T')
560-
class A:
561-
def __init__(self, a: T, b: T) -> None: pass
562-
class B: pass
563-
class C: pass
564-
a, b, c = Undefined, Undefined, Undefined # type: (A, B, C)
565-
566-
a = A[B](b, c) # E: Argument 2 to "A" has incompatible type "C"; expected "B"
567-
a = A[B](c, b) # E: Argument 1 to "A" has incompatible type "C"; expected "B"
568-
b = A[B](b, b) # E: Incompatible types in assignment (expression has type "A", variable has type "B")
569-
570-
a = A[B](b, b)
571-
a = A[C](c, c)
437+
class A(Generic[T, S]): pass
438+
A[int, str]() # E: Generic type not valid as an expression any more (use '# type:' comment instead)
439+
A[int]() # E: Generic type not valid as an expression any more (use '# type:' comment instead)
440+
[out]
572441

573-
[case testInvalidTypeApplicationTarget]
442+
[case testInvalidTypeApplicationTarget3]
574443
from typing import Undefined
575444
a = Undefined # type: A
576445
class A: pass
577446
a[A]() # Fail
578447
A[A]() # Fail
579448
[out]
580449
main, line 4: Value of type "A" is not indexable
581-
main, line 5: Type application targets a non-generic function
582-
583-
[case testInvalidNumberOfGenericArgsInTypeApplication]
584-
from typing import TypeVar, Generic
585-
T = TypeVar('T')
586-
S = TypeVar('S')
587-
class A(Generic[T, S]): pass
588-
x = A[int, str, int]() # E: Type application has too many types (2 expected)
589-
x = A[int]() # E: Type application has too few types (2 expected)
590-
[out]
450+
main, line 5: Generic type not valid as an expression any more (use '# type:' comment instead)
591451

592452

593453
-- Multiple assignment with lists
@@ -603,20 +463,26 @@ a = Undefined # type: A
603463
b = Undefined # type: B
604464
b2 = Undefined # type: B2
605465

606-
a, b = List[A]() # E: Incompatible types in assignment (expression has type "A", variable has type "B")
607-
b, a = List[A]() # E: Incompatible types in assignment (expression has type "A", variable has type "B")
608-
b2, b2 = List[B]() # E: Incompatible types in assignment (expression has type "B", variable has type "B2")
466+
list_a = [a]
467+
list_b = [b]
468+
list_b2 = [b2]
609469

610-
a, a = List[A]()
611-
b, b2, b = List[B2]()
470+
a, b = list_a # E: Incompatible types in assignment (expression has type "A", variable has type "B")
471+
b, a = list_a # E: Incompatible types in assignment (expression has type "A", variable has type "B")
472+
b2, b2 = list_b # E: Incompatible types in assignment (expression has type "B", variable has type "B2")
473+
474+
a, a = list_a
475+
b, b2, b = list_b2
612476
[builtins fixtures/for.py]
613477

614478
[case testMultipleAssignmentWithListsInInitialization]
615479
from typing import List
616480
class A: pass
617-
a, b = List[object]() # type: (A, object) # E: Incompatible types in assignment (expression has type "object", variable has type "A")
618-
c, d = List[object]() # type: (object, A) # E: Incompatible types in assignment (expression has type "object", variable has type "A")
619-
e, f = List[A]() # type: (A, object)
481+
list_object = [object()]
482+
list_a = [A()]
483+
a, b = list_object # type: (A, object) # E: Incompatible types in assignment (expression has type "object", variable has type "A")
484+
c, d = list_object # type: (object, A) # E: Incompatible types in assignment (expression has type "object", variable has type "A")
485+
e, f = list_a # type: (A, object)
620486
[builtins fixtures/for.py]
621487

622488
[case testMultipleAssignmentWithListAndIndexing]
@@ -743,22 +609,6 @@ b = f([b])
743609
b = f(b)
744610
[builtins fixtures/list.py]
745611

746-
[case testOverloadedGenericFunction]
747-
from typing import overload, TypeVar, Undefined
748-
t = TypeVar('t')
749-
class A: pass
750-
class B: pass
751-
752-
@overload
753-
def f(x: int, a: A) -> A: pass
754-
@overload
755-
def f(x: str, a: t) -> t: pass
756-
757-
a, b = Undefined, Undefined # type: (A, B)
758-
b = f[B]('', b)
759-
a = f[B]('', b) # E: Incompatible types in assignment (expression has type "B", variable has type "A")
760-
f[B](1, a) # E: No overload variant of "f" matches argument types
761-
762612

763613
-- Type variable scoping
764614
-- ---------------------

mypy/test/data/check-inference-context.test

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -453,8 +453,10 @@ t = TypeVar('t')
453453
class A(Generic[t]): pass
454454
class B: pass
455455
class C: pass
456-
d = {A() : A[C](),
457-
A[B]() : A()} # type: Dict[A[B], A[C]]
456+
a_b = A() # type: A[B]
457+
a_c = A() # type: A[C]
458+
d = {A() : a_c,
459+
a_b : A()} # type: Dict[A[B], A[C]]
458460
[builtins fixtures/dict.py]
459461

460462

@@ -504,7 +506,8 @@ from typing import TypeVar, Generic
504506
from abc import abstractmethod, ABCMeta
505507
t = TypeVar('t')
506508
x = A() # type: I[int]
507-
y = A[object]() # type: I[int] # E: Incompatible types in assignment (expression has type A[object], variable has type I[int])
509+
a_object = A() # type: A[object]
510+
y = a_object # type: I[int] # E: Incompatible types in assignment (expression has type A[object], variable has type I[int])
508511

509512
class I(Generic[t]):
510513
@abstractmethod
@@ -517,7 +520,8 @@ from typing import TypeVar, Generic
517520
from abc import abstractmethod, ABCMeta
518521
t = TypeVar('t')
519522
a = f(A()) # type: A[int]
520-
aa = f(A[int]())
523+
a_int = A() # type: A[int]
524+
aa = f(a_int)
521525
class I(Generic[t]): pass
522526
class A(I[t], Generic[t]): pass
523527
def f(i: I[t]) -> A[t]: pass
@@ -529,19 +533,7 @@ class set(Generic[t]):
529533
def __init__(self, iterable: Iterable[t]) -> None: pass
530534
b = bool()
531535
l = set([b])
532-
l = set[bool]([])
533-
l = set[object]([]) # E: Incompatible types in assignment (expression has type set[object], variable has type set[bool])
534-
[builtins fixtures/for.py]
535-
536-
[case testInferenceWithAbstractClassContext4]
537-
from typing import TypeVar, Generic, Iterable
538-
t = TypeVar('t')
539-
class set(Generic[t]): pass
540-
def f(iterable: Iterable[t]) -> set[t]: pass
541-
b = bool()
542-
l = f([b])
543-
l = f[bool]([])
544-
l = f[object]([]) # E: Incompatible types in assignment (expression has type set[object], variable has type set[bool])
536+
l = set([object()]) # E: List item 1 has incompatible type "object"
545537
[builtins fixtures/for.py]
546538

547539

0 commit comments

Comments
 (0)