Skip to content

Commit

Permalink
Fix wrong type argument value inference based on context
Browse files Browse the repository at this point in the history
Ignore type inference context if the return value of a function is a
type variable type with values.

Fix #360.
  • Loading branch information
JukkaL committed Sep 15, 2014
1 parent 17e2cf0 commit 0f5b09b
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 1 deletion.
9 changes: 8 additions & 1 deletion mypy/checkexpr.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,14 @@ def infer_function_type_arguments_using_context(
# special ErasedType type. On the other hand, class type variables are
# valid results.
erased_ctx = replace_func_type_vars(ctx, ErasedType())
args = infer_type_arguments(callable.type_var_ids(), callable.ret_type,
ret_type = callable.ret_type
if isinstance(ret_type, TypeVar):
if ret_type.values:
# The return type is a type variable with values, but we can't easily restrict
# type inference to conform to the valid values. Give up and just use function
# arguments for type inference.
ret_type = NoneTyp()
args = infer_type_arguments(callable.type_var_ids(), ret_type,
erased_ctx, self.chk.basic_types())
# Only substite non-None and non-erased types.
new_args = [] # type: List[Type]
Expand Down
25 changes: 25 additions & 0 deletions mypy/test/data/check-typevar-values.test
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,31 @@ main, line 10: Incompatible types in assignment (expression has type "str", vari
main, line 11: "int" has no attribute "foo"
main, line 11: "str" has no attribute "foo"

[case testTypeVarWithValueInferredFromObjectReturnTypeContext]
from typing import typevar
T = typevar('T', values=(int, str))
def c1(x: object) -> None: pass
def c2(x: int) -> None: pass
def c3(x: str) -> None: pass
def g(x: T) -> T: pass
c1(g(''))
c2(g(1))
c3(g(''))
c2(g('')) # E: Argument 1 to "c2" has incompatible type "str"; expected "int"
c3(g(1)) # E: Argument 1 to "c3" has incompatible type "int"; expected "str"

[case testTypeVarWithValueInferredFromObjectReturnTypeContext2]
from typing import typevar
T = typevar('T', values=(int, str))
class ss(str): pass
def c(x: ss) -> None: pass
def g(x: T) -> T: pass
c(g(''))
c(g(1))
[out]
main, line 6: Argument 1 to "c" has incompatible type "str"; expected "ss"
main, line 7: Argument 1 to "c" has incompatible type "int"; expected "ss"


-- Special cases
-- -------------
Expand Down

0 comments on commit 0f5b09b

Please sign in to comment.