-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
Generator fixup #1137
Generator fixup #1137
Changes from all commits
074dada
04cd7fa
8a7024d
68aba19
9dc2969
cab403c
4356244
b4bf34e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -51,6 +51,42 @@ def g() -> None: | |
[out] | ||
main: note: In function "g": | ||
|
||
[case testReturnInGenerator] | ||
from typing import Generator | ||
def f() -> Generator[int, None, str]: | ||
yield 1 | ||
return "foo" | ||
[out] | ||
|
||
[case testEmptyReturnInGenerator] | ||
from typing import Generator | ||
def f() -> Generator[int, None, str]: | ||
yield 1 | ||
return # E: Return value expected | ||
[out] | ||
main: note: In function "f": | ||
|
||
[case testEmptyReturnInNoneTypedGenerator] | ||
from typing import Generator | ||
def f() -> Generator[int, None, None]: | ||
yield 1 | ||
return | ||
[out] | ||
|
||
[case testNonEmptyReturnInNoneTypedGenerator] | ||
from typing import Generator | ||
def f() -> Generator[int, None, None]: | ||
yield 1 | ||
return 42 # E: No return value expected | ||
[out] | ||
main: note: In function "f": | ||
|
||
[case testReturnInIterator] | ||
from typing import Iterator | ||
def f() -> Iterator[int]: | ||
yield 1 | ||
return "foo" | ||
[out] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess there are also cases where the return type is There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, thanks for catching that! Added. |
||
|
||
-- If statement | ||
-- ------------ | ||
|
@@ -675,8 +711,8 @@ def f() -> Any: | |
|
||
[case testYieldInFunctionReturningFunction] | ||
from typing import Callable | ||
def f() -> Callable[[], None]: | ||
yield object() # E: The return type of a generator function should be "Generator" or one of its supertypes | ||
def f() -> Callable[[], None]: # E: The return type of a generator function should be "Generator" or one of its supertypes | ||
yield object() | ||
[out] | ||
main: note: In function "f": | ||
|
||
|
@@ -687,8 +723,8 @@ def f(): | |
|
||
[case testWithInvalidInstanceReturnType] | ||
import typing | ||
def f() -> int: | ||
yield 1 # E: The return type of a generator function should be "Generator" or one of its supertypes | ||
def f() -> int: # E: The return type of a generator function should be "Generator" or one of its supertypes | ||
yield 1 | ||
[builtins fixtures/for.py] | ||
[out] | ||
main: note: In function "f": | ||
|
@@ -715,6 +751,22 @@ def f() -> Iterator[None]: | |
yield | ||
[builtins fixtures/for.py] | ||
|
||
[case testYieldWithNoValueWhenValueRequired] | ||
from typing import Iterator | ||
def f() -> Iterator[int]: | ||
yield # E: Yield value expected | ||
[builtins fixtures/for.py] | ||
[out] | ||
main: note: In function "f": | ||
|
||
[case testYieldWithExplicitNone] | ||
from typing import Iterator | ||
def f() -> Iterator[None]: | ||
yield None # E: Incompatible types in yield (actual type None, expected type None) | ||
[builtins fixtures/for.py] | ||
[out] | ||
main: note: In function "f": | ||
|
||
|
||
-- Yield from statement | ||
-- -------------------- | ||
|
@@ -746,17 +798,17 @@ def f() -> Any: | |
from typing import Iterator, Callable | ||
def g() -> Iterator[int]: | ||
yield 42 | ||
def f() -> Callable[[], None]: | ||
yield from g() # E: Iterable function return type expected for "yield from" | ||
def f() -> Callable[[], None]: # E: The return type of a generator function should be "Generator" or one of its supertypes | ||
yield from g() | ||
[out] | ||
main: note: In function "f": | ||
|
||
[case testYieldFromNotIterableReturnType] | ||
from typing import Iterator | ||
def g() -> Iterator[int]: | ||
yield 42 | ||
def f() -> int: | ||
yield from g() # E: Iterable function return type expected for "yield from" | ||
def f() -> int: # E: The return type of a generator function should be "Generator" or one of its supertypes | ||
yield from g() | ||
[out] | ||
main: note: In function "f": | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would rather fix up f()'s declaration to define the right return type? (e.g. Iterator[int])
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless you're aiming for two birds with one stone?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As it stands, it's checking both at once. A common idiom in the tests seems to be purposefully introducing type errors to check the error message. Testing the Generator function return type enforcement is important, but I don't have much of an opinion on whether it should be done in this function or a separate one.