Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions mypy/checkexpr.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@
covers_at_runtime,
find_member,
has_any_type,
is_proper_subtype,
is_same_type,
is_subtype,
merge_typevars_in_callables_by_name,
Expand Down Expand Up @@ -6941,6 +6942,16 @@ def any_causes_overload_ambiguity(
for formal in formals:
matching_formals.append(matched_callable.arg_types[formal])
if not all_same_types(matching_formals) and not all_same_types(matching_returns):
if (
not arg_kinds[arg_idx].is_star()
and not isinstance(get_proper_type(arg_type), FunctionLike)
and all(is_proper_subtype(arg_type, formal) for formal in matching_formals)
):
# These matches do not depend on Any being compatible with arbitrary
# types. For example, SubBox[Any] matches both SubBox[Any] and Box[Any].
# Callable subtyping can still accept gradual parameter lists, so keep
# the conservative ambiguity check for callable arguments.
continue
# Any maps to multiple different types, and the return types of these items differ.
return True

Expand Down
21 changes: 21 additions & 0 deletions test-data/unit/check-overloading.test
Original file line number Diff line number Diff line change
Expand Up @@ -1812,6 +1812,27 @@ reveal_type(f(d)) # N: Revealed type is "builtins.list[builtins.int]"

[builtins fixtures/list.pyi]

[case testOverloadWithNestedAnyNotCausingAmbiguity]
from typing import Any, Generic, TypeVar, overload
T = TypeVar('T')

class Box(Generic[T]): pass
class SubBox(Box[T]): pass

@overload
def choose(value: SubBox[T]) -> SubBox[T]: ...
@overload
def choose(value: Box[T]) -> Box[T]: ...
def choose(value): pass

value: SubBox[Any]
reveal_type(choose(value)) # N: Revealed type is "__main__.SubBox[Any]"
reveal_type(choose(value=value)) # N: Revealed type is "__main__.SubBox[Any]"
nested: SubBox[Box[Any]]
reveal_type(choose(nested)) # N: Revealed type is "__main__.SubBox[__main__.Box[Any]]"
any_value: Any
reveal_type(choose(any_value)) # N: Revealed type is "Any"

[case testOverloadWithOverlappingItemsAndAnyArgument10]
from typing import overload, Any

Expand Down
14 changes: 14 additions & 0 deletions test-data/unit/pythoneval.test
Original file line number Diff line number Diff line change
Expand Up @@ -2287,6 +2287,20 @@ y = t"hello {1}"
[out]
m.pyi:3: error: T-strings: requires Python 3.14 or newer (current target: Python 3.13)

[case testReversedListWithNestedAny]
# flags: --python-version=3.12 --warn-return-any
from typing import Any, assert_type

def last_value(values: list[tuple[Any, int]]) -> int | None:
for key, value in reversed(values):
assert_type(value, int)
return value
return None

assert last_value([('first', 1), ('last', 2)]) == 2
assert last_value([]) is None
[out]

[case testNativeParserStarUnpackRequiresPython311]
# flags: --python-version=3.10 --native-parser
from typing_extensions import TypeVarTuple, Unpack
Expand Down
Loading