8000 Extend special case for context-based typevar inference to typevar un… · python/mypy@a0307b5 · GitHub
[go: up one dir, main page]

Skip to content

Commit a0307b5

Browse files
authored
Extend special case for context-based typevar inference to typevar unions in return position (#18976)
* Fixes #17221. * Fixes #17654. * Fixes #17553. * Fixes #17536. * Fixes #16659. * Fixes #16267. * Fixes #15755. * Fixes #15150. * Fixes #14664. * Incidentally improves error message in #12156. * Fixes #12092. * Fixes #11985. * Improves #11455 (but the problem with union `TypeVar | SomeFixedType` reported in comments there remains). * Fixes #10426. When using context, we can perform some overly optimistic inference when return type is `T1 | T2`. This breaks in important case of `builtins.min` when `default` and `key` are passed, essentially making them always incompatible. This is not the most principled approach, but let's see the primer results. This resolves quite a few issues (some of them duplicates, but some - substantially different), `min` problem was a very popular one... Diff run: sterliakov/mypy-issues#30
1 parent 9e45dad commit a0307b5

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

mypy/checkexpr.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2013,7 +2013,12 @@ def infer_function_type_arguments_using_context(
20132013
# variables in an expression are inferred at the same time.
20142014
# (And this is hard, also we need to be careful with lambdas that require
20152015
# two passes.)
2016-
if isinstance(ret_type, TypeVarType):
2016+
proper_ret = get_proper_type(ret_type)
2017+
if (
2018+
isinstance(proper_ret, TypeVarType)
2019+
or isinstance(proper_ret, UnionType)
2020+
and all(isinstance(get_proper_type(u), TypeVarType) for u in proper_ret.items)
2021+
):
20172022
# Another special case: the return type is a type variable. If it's unrestricted,
20182023
# we could infer a too general type for the type variable if we use context,
20192024
# and this could result in confusing and spurious type errors elsewhere.

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1495,3 +1495,18 @@ def g(b: Optional[str]) -> None:
14951495
z: Callable[[], str] = lambda: reveal_type(b) # N: Revealed type is "builtins.str"
14961496
f2(lambda: reveal_type(b)) # N: Revealed type is "builtins.str"
14971497
lambda: reveal_type(b) # N: Revealed type is "builtins.str"
1498+
1499+
[case testInferenceContextReturningTypeVarUnion]
1500+
from collections.abc import Callable, Iterable
1501+
from typing import TypeVar, Union
1502+
1503+
_T1 = TypeVar("_T1")
1504+
_T2 = TypeVar("_T2")
1505+
1506+
def mymin(
1507+
iterable: Iterable[_T1], /, *, key: Callable[[_T1], int], default: _T2
1508+
) -> Union[_T1, _T2]: ...
1509+
1510+
def check(paths: Iterable[str], key: Callable[[str], int]) -> Union[str, None]:
1511+
return mymin(paths, key=key, default=None)
1512+
[builtins fixtures/tuple.pyi]

0 commit comments

Comments
 (0)
0