Skip to content

Commit

Permalink
Allow substituting typevar-with-values for typevar-with-values (#1469)
Browse files Browse the repository at this point in the history
This is needed for subtyping of generic function with type variables
with values to work correctly, which will be needed for #1261.
  • Loading branch information
rwbarton authored and gvanrossum committed May 3, 2016
1 parent 410bf37 commit a62caad
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 1 deletion.
9 changes: 8 additions & 1 deletion mypy/applytype.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from typing import List, Dict

import mypy.subtypes
from mypy.sametypes import is_same_type
from mypy.expandtype import expand_type
from mypy.types import Type, CallableType, AnyType, Void
from mypy.types import Type, TypeVarType, CallableType, AnyType, Void
from mypy.messages import MessageBuilder
from mypy.nodes import Context

Expand All @@ -29,6 +30,12 @@ def apply_generic_arguments(callable: CallableType, types: List[Type],
if values and type:
if isinstance(type, AnyType):
continue
if isinstance(type, TypeVarType) and type.values:
# Allow substituting T1 for T if every allowed value of T1
# is also a legal value of T.
if all(any(is_same_type(v, v1) for v in values)
for v1 in type.values):
continue
for value in values:
if mypy.subtypes.is_subtype(type, value):
types[i] = value
Expand Down
14 changes: 14 additions & 0 deletions mypy/test/data/check-typevar-values.test
Original file line number Diff line number Diff line change
Expand Up @@ -465,3 +465,17 @@ def g(x: str) -> str: return x
main: note: In function "f":
main:7: error: Incompatible types in assignment (expression has type "object", variable has type "int")
main:7: error: Incompatible types in assignment (expression has type "object", variable has type "str")

[case testGenericFunctionSubtypingWithTypevarValues]
from typing import TypeVar
class A: pass
T = TypeVar('T', int, str)
U = TypeVar('U', str, A, int)
def f(x: T) -> T: pass
def g(x: U) -> U: pass
a = f
a = f
a = g
b = g
b = g
b = f # E: Incompatible types in assignment (expression has type Callable[[T], T], variable has type Callable[[U], U])

0 comments on commit a62caad

Please sign in to comment.