Skip to content

Fix overload interaction with Any #5233

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 18, 2018
Merged
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
6 changes: 4 additions & 2 deletions mypy/checkexpr.py
Original file line number Diff line number Diff line change
Expand Up @@ -1304,8 +1304,10 @@ def infer_overload_return_type(self,
return None
elif any_causes_overload_ambiguity(matches, return_types, arg_types, arg_kinds, arg_names):
# An argument of type or containing the type 'Any' caused ambiguity.
if all(is_subtype(ret_type, return_types[-1]) for ret_type in return_types[:-1]):
# The last match is a supertype of all the previous ones, so it's safe
if all(is_subtype(ret_type, return_types[-1]) and
is_subtype(return_types[-1], ret_type)
for ret_type in return_types[:-1]):
# The last match is mutually compatible with all previous ones, so it's safe
# to return that inferred type.
return return_types[-1], inferred_types[-1]
else:
Expand Down
17 changes: 8 additions & 9 deletions test-data/unit/check-overloading.test
Original file line number Diff line number Diff line change
Expand Up @@ -1276,7 +1276,7 @@ def f(x: object) -> object: ...
def f(x): pass

a: Any
reveal_type(f(a)) # E: Revealed type is 'builtins.object'
reveal_type(f(a)) # E: Revealed type is 'Any'

[case testOverloadWithOverlappingItemsAndAnyArgument2]
from typing import overload, Any
Expand All @@ -1288,7 +1288,7 @@ def f(x: float) -> float: ...
def f(x): pass

a: Any
reveal_type(f(a)) # E: Revealed type is 'builtins.float'
reveal_type(f(a)) # E: Revealed type is 'Any'

[case testOverloadWithOverlappingItemsAndAnyArgument3]
from typing import overload, Any
Expand All @@ -1312,17 +1312,16 @@ def f(x: object, y: int, z: str) -> object: ...
def f(x): pass

a: Any
# Any causes ambiguity; we fall back to returning object since it's a
# supertype of int
reveal_type(f(a, 1, '')) # E: Revealed type is 'builtins.object'
# Any causes ambiguity
reveal_type(f(a, 1, '')) # E: Revealed type is 'Any'
# Any causes no ambiguity
reveal_type(f(1, a, a)) # E: Revealed type is 'builtins.int'
reveal_type(f('', a, a)) # E: Revealed type is 'builtins.object'
# Like above, but use keyword arguments.
reveal_type(f(y=1, z='', x=a)) # E: Revealed type is 'builtins.object'
reveal_type(f(y=1, z='', x=a)) # E: Revealed type is 'Any'
reveal_type(f(y=a, z='', x=1)) # E: Revealed type is 'builtins.int'
reveal_type(f(z='', x=1, y=a)) # E: Revealed type is 'builtins.int'
reveal_type(f(z='', x=a, y=1)) # E: Revealed type is 'builtins.object'
reveal_type(f(z='', x=a, y=1)) # E: Revealed type is 'Any'

[case testOverloadWithOverlappingItemsAndAnyArgument5]
from typing import overload, Any, Union
Expand All @@ -1334,7 +1333,7 @@ def f(x: Union[int, float]) -> float: ...
def f(x): pass

a: Any
reveal_type(f(a)) # E: Revealed type is 'builtins.float'
reveal_type(f(a)) # E: Revealed type is 'Any'

[case testOverloadWithOverlappingItemsAndAnyArgument6]
from typing import overload, Any
Expand Down Expand Up @@ -1372,7 +1371,7 @@ def g(x): pass

a: Any
reveal_type(f(1, *a)) # E: Revealed type is 'builtins.int'
reveal_type(g(1, *a)) # E: Revealed type is 'builtins.object'
reveal_type(g(1, *a)) # E: Revealed type is 'Any'

[case testOverloadWithOverlappingItemsAndAnyArgument8]
from typing import overload, Any
Expand Down
12 changes: 10 additions & 2 deletions test-data/unit/python2eval.test
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ print b.x + 1
[out]
4

[case testReModuleBytesPython2]
[case testReModuleBytes_python2]
# Regression tests for various overloads in the re module -- bytes version
import re
if False:
Expand All @@ -365,7 +365,7 @@ if False:
re.subn(bpat, lambda m: b'', b'')[0] + b''
[out]

[case testReModuleStringPython2]
[case testReModuleString_python2]
# Regression tests for various overloads in the re module -- string version
import re
ure = u'a+'
Expand Down Expand Up @@ -393,3 +393,11 @@ def g(): # type: () -> int
yield
[out]
_program.py:2: error: The return type of a generator function should be "Generator" or one of its supertypes

[case testOsPathJoinWorksWithAny_python2]
import os
def f(): # no annotation
return 'tests'
path = 'test'
path = os.path.join(f(), 'test.py')
[out]
2 changes: 2 additions & 0 deletions test-data/unit/pythoneval.test
Original file line number Diff line number Diff line change
Expand Up @@ -1109,9 +1109,11 @@ async def main() -> None:
((a_x, a_y),) = await asyncio.gather(get_location('start'))
reveal_type(a_x)
reveal_type(a_y)
reveal_type(asyncio.gather(*[asyncio.sleep(1), asyncio.sleep(1)]))
[out]
_testAsyncioGatherPreciseType.py:9: error: Revealed type is 'builtins.str'
_testAsyncioGatherPreciseType.py:10: error: Revealed type is 'builtins.str'
_testAsyncioGatherPreciseType.py:11: error: Revealed type is 'asyncio.futures.Future[builtins.tuple[Any]]'

[case testMultipleInheritanceWorksWithTupleTypeGeneric]
from typing import SupportsAbs, NamedTuple
Expand Down