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

Starting from version 1.0.0, a union of Generators is (sometimes) treated as if it has no ReturnType #15141

Closed
mwchase opened this issue Apr 26, 2023 · 4 comments · Fixed by #16717
Labels
bug mypy got something wrong good-second-issue

Comments

@mwchase
Copy link

mwchase commented Apr 26, 2023

Bug Report

Starting from version 1.0.0, yield from a union on Generator types generates the error Function does not return a value [func-returns-value], and attempting to use the return reveals that Mypy is, in fact, treating it as if it's None.

There are ways around this; it appears that the inference is a little smarter at function boundaries than in-line, so I've just defined a bunch of helper functions to work around it for now.

To Reproduce

from typing import Generator, TypeVar

T = TypeVar("T")


def my_iter(arg: Generator[int, None, T] | Generator[str, None, T]) -> Generator[int | str, None, T]:
    return (yield from arg)

(https://mypy-play.net/?mypy=0.991&python=3.11&gist=5c3183a0d4d1c02161211b01654d519f)

(The repro is working with YieldType, but in my code it's changing ReturnType. It breaks either way around.)

Actual Behavior

On post-1.0.0 versions:

main.py:7: error: Function does not return a value  [func-returns-value]
main.py:7: error: Incompatible return value type (got "None", expected "T")  [return-value]
Found 2 errors in 1 file (checked 1 source file)

Pre-1.0.0, produces no output.

@mwchase mwchase added the bug mypy got something wrong label Apr 26, 2023
@hauntsaninja
Copy link
Collaborator

I bisected this back to #14224 , which fixed a case where we were basically not type checking coroutines and generators. My guess is you'd need to make a similar change in

def visit_yield_from_expr(self, e: YieldFromExpr, allow_none_return: bool = False) -> Type:

@hauntsaninja
Copy link
Collaborator

By the way, did you happen to encounter this regression in an open source project?

@mwchase
Copy link
Author

mwchase commented May 2, 2023

This is in something I'm working on that's technically open source, but not in any convenient way; I don't really want to publicize it anywhere before it's useful.

EDIT (May 3): Also, it uses some custom plugins, so I think currently it can't go in mypy_primer anyway. I forgot about that.

@hauntsaninja
Copy link
Collaborator

hauntsaninja commented May 2, 2023

Thanks! I'd love to include it in mypy_primer so we avoid regressions on that project in the future; if you're ever comfortable with that at some point, feel free to post a link to the project here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong good-second-issue
Projects
None yet
2 participants