Skip to content

Commit 0f5b09b

Browse files
committed
Fix wrong type argument value inference based on context
Ignore type inference context if the return value of a function is a type variable type with values. Fix #360.
1 parent 17e2cf0 commit 0f5b09b

File tree

2 files changed

+33
-1
lines changed

2 files changed

+33
-1
lines changed

mypy/checkexpr.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,14 @@ def infer_function_type_arguments_using_context(
275275
# special ErasedType type. On the other hand, class type variables are
276276
# valid results.
277277
erased_ctx = replace_func_type_vars(ctx, ErasedType())
278-
args = infer_type_arguments(callable.type_var_ids(), callable.ret_type,
278+
ret_type = callable.ret_type
279+
if isinstance(ret_type, TypeVar):
280+
if ret_type.values:
281+
# The return type is a type variable with values, but we can't easily restrict
282+
# type inference to conform to the valid values. Give up and just use function
283+
# arguments for type inference.
284+
ret_type = NoneTyp()
285+
args = infer_type_arguments(callable.type_var_ids(), ret_type,
279286
erased_ctx, self.chk.basic_types())
280287
# Only substite non-None and non-erased types.
281288
new_args = [] # type: List[Type]

mypy/test/data/check-typevar-values.test

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,31 @@ main, line 10: Incompatible types in assignment (expression has type "str", vari
411411
main, line 11: "int" has no attribute "foo"
412412
main, line 11: "str" has no attribute "foo"
413413

414+
[case testTypeVarWithValueInferredFromObjectReturnTypeContext]
415+
from typing import typevar
416+
T = typevar('T', values=(int, str))
417+
def c1(x: object) -> None: pass
418+
def c2(x: int) -> None: pass
419+
def c3(x: str) -> None: pass
420+
def g(x: T) -> T: pass
421+
c1(g(''))
422+
c2(g(1))
423+
c3(g(''))
424+
c2(g('')) # E: Argument 1 to "c2" has incompatible type "str"; expected "int"
425+
c3(g(1)) # E: Argument 1 to "c3" has incompatible type "int"; expected "str"
426+
427+
[case testTypeVarWithValueInferredFromObjectReturnTypeContext2]
428+
from typing import typevar
429+
T = typevar('T', values=(int, str))
430+
class ss(str): pass
431+
def c(x: ss) -> None: pass
432+
def g(x: T) -> T: pass
433+
c(g(''))
434+
c(g(1))
435+
[out]
436+
main, line 6: Argument 1 to "c" has incompatible type "str"; expected "ss"
437+
main, line 7: Argument 1 to "c" has incompatible type "int"; expected "ss"
438+
414439

415440
-- Special cases
416441
-- -------------

0 commit comments

Comments
 (0)