Skip to content
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

different treatment of untyped defs, typed defs, and lambdas #5746

Closed
hashbrowncipher opened this issue Oct 7, 2018 · 2 comments
Closed

Comments

@hashbrowncipher
Copy link

hashbrowncipher commented Oct 7, 2018

Edit: see first comment

Test case:

  1 from typing import Callable
  2 from typing import Union
  3
  4
  5 def works(arg: Union[int, str]) -> Callable[[], int]:
  6     if isinstance(arg, str):
  7         def ret():
  8             return len(arg)
  9         return ret
 10     elif isinstance(arg, int):
 11         def ret():
 12             return arg + 8
 13         return ret
 14
 15
 16 def fails1(arg: Union[int, str]) -> Callable[[], int]:
 17     if isinstance(arg, str):
 18         def ret() -> int:
 19             return len(arg)
 20         return ret
 21     elif isinstance(arg, int):
 22         def ret() -> int:
 23             return arg + 8
 24         return ret
 25
 26
 27 def fails2(arg: Union[int, str]) -> Callable[[], int]:
 28     if isinstance(arg, str):
 29         return lambda: len(arg)
 30     elif isinstance(arg, int):
 31         return lambda: arg + 8

Actual output:

$ mypy --version
mypy 0.640+dev.e12be3ba9e6be3e9242e3a81ffaa9b3a136876fe
$ python3 --version
Python 3.7.0
$ mypy lambdas_n_defs.py
lambdas_n_defs.py:19: error: Argument 1 to "len" has incompatible type "Union[int, str]"; expected "Sized"
lambdas_n_defs.py:23: error: Unsupported operand types for + ("str" and "int")
lambdas_n_defs.py:23: note: Left operand is of type "Union[int, str]"
lambdas_n_defs.py:29: error: Argument 1 to "len" has incompatible type "Union[int, str]"; expected "Sized"
lambdas_n_defs.py:31: error: Unsupported operand types for + ("str" and "int")
lambdas_n_defs.py:31: note: Left operand is of type "Union[int, str]"

Expected output: none, because I believe mypy should treat fails1() and fails2() identically to works()

@hashbrowncipher
Copy link
Author

I've realized that the only reason that works() works is because I wasn't using --check-untyped-defs, so here's a second test case that gets to what I actually care about:

$ python3 --version
Python 3.7.0
$ mypy --version
mypy 0.640+dev.e12be3ba9e6be3e9242e3a81ffaa9b3a136876fe
$ nl -ba lambdas_n_defs.py
     1	from typing import Callable
     2	from typing import Union
     3
     4
     5	def works(arg: Union[int, str]) -> Callable[[], int]:
     6	    if isinstance(arg, str):
     7	        answer = len(arg)
     8
     9	        def ret() -> int:
    10	            return answer
    11	        return ret
    12	    elif isinstance(arg, int):
    13	        answer = arg + 8
    14
    15	        def ret() -> int:
    16	            return answer
    17	        return ret
    18
    19
    20	def fails(arg: Union[int, str]) -> Callable[[], int]:
    21	    if isinstance(arg, str):
    22	        def ret() -> int:
    23	            return len(arg)
    24	        return ret
    25	    elif isinstance(arg, int):
    26	        def ret() -> int:
    27	            return arg + 8
    28	        return ret
$ mypy --strict lambdas_n_defs.py
lambdas_n_defs.py:23: error: Argument 1 to "len" has incompatible type "Union[int, str]"; expected "Sized"
lambdas_n_defs.py:27: error: Unsupported operand types for + ("str" and "int")
lambdas_n_defs.py:27: note: Left operand is of type "Union[int, str]"

@ilevkivskyi
Copy link
Member

Thanks for reporting!

This is a duplicate of #2608 (types don't propagate to nested functions, including lambdas), see also #4973.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants