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

mypy is confused by return values from generators #695

Closed
gvanrossum opened this issue May 20, 2015 · 6 comments · Fixed by #1137
Closed

mypy is confused by return values from generators #695

gvanrossum opened this issue May 20, 2015 · 6 comments · Fixed by #1137
Assignees
Labels
bug mypy got something wrong

Comments

@gvanrossum
Copy link
Member

This is fine:

from typing import Iterator

def foo() -> Iterator[int]:
    yield 42

x = next(foo()) + 1000
print(x)

But now try this:

from typing import Iterator

def foo() -> Iterator[int]:
    yield 42
    return 'abc'

This complains about the return statement:

g.py, line 5: Incompatible return value type: expected typing.Iterator[builtins.int], got builtins.str

It's matching the generator return value (which is only accessible by a caller that uses yield from) to the declared return type (which is just the type of what you get by calling foo().

@spkersten
Copy link
Contributor

I've been fixing this (see spkersten/generator). Type checking return already works in that branch, only yield from and some special casing for coroutines need a bit more work.

On 21 mei 2015, at 00:11, Guido van Rossum notifications@github.com wrote:

This is fine:

from typing import Iterator

def foo() -> Iterator[int]:
yield 42

x = next(foo()) + 1000
print(x)
But now try this:

from typing import Iterator

def foo() -> Iterator[int]:
yield 42
return 'abc'
This complains about the return statement:

g.py, line 5: Incompatible return value type: expected typing.Iterator[builtins.int], got builtins.str
It's matching the generator return value (which is only accessible by a caller that uses yield from) to the declared return type (which is just the type of what you get by calling foo().


Reply to this email directly or view it on GitHub.

@gvanrossum
Copy link
Member Author

@spkersten, do you still have that branch? If not I'm probably going to look into this -- there also seems overlap with #642 and #1011.

@gvanrossum
Copy link
Member Author

FWIW, I think that the example using return 'abc' should be rejected, but the error message should indicate that a generator declared to return an Iterator should not return a value in a return statement. However, if the function return is declared as -> Generator[X, Y, Z] then the return expression should be type-checked against Z, and the value returned by a yield expression should be type-checked against Y. IOW, ue these mnemonics:

def foo() -> Generator[X, Y, Z]:
    yield x   # or "yield" if X is None
    y = yield x   # or "y = yield" if X is None (either way only if Y isn't None)
    return z  # or "return" if Z is None

We could treat Iterator[X] as Generator[X, Y, Z] except I still think that even return None should be disallowed -- only return should be allowed if the function declaration doesn't use Generator (because that's the pre-3.3 way).

@gvanrossum gvanrossum added the bug mypy got something wrong label Jan 15, 2016
@gvanrossum
Copy link
Member Author

@sakana will address this next. (@jukka: can you add @sakana as a committer? It's David. :-)

@ddfisher
Copy link
Collaborator

I'm @ddfisher now!

@JukkaL
Copy link
Collaborator

JukkaL commented Jan 15, 2016

Added @ddfisher.

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

Successfully merging a pull request may close this issue.

4 participants