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

Fix crash with yield in comprehension #12048

Merged
merged 4 commits into from
Jan 24, 2022
Merged

Fix crash with yield in comprehension #12048

merged 4 commits into from
Jan 24, 2022

Conversation

alexbouayad
Copy link
Contributor

@alexbouayad alexbouayad commented Jan 23, 2022

Fixes #10189

Produce an error when encountering a yield expression (both yield and yield from clauses) in comprehensions and generator expressions. The latter is a syntax error in python 3.8+; see #10189 and also python issue 10544.

Test Plan

Added testYieldOutsideFunction (in check-semanal-error.test).

mypy/semanal.py Outdated
if not self.is_func_scope(): # not sure
self.fail('"yield from" outside function', e, serious=True, blocker=True)
if not self.is_func_scope() or self.is_comprehension_stack[-1]:
self.fail('"yield from" outside function or lambda', e, serious=True, blocker=True)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need the "or lambda" part. Lambdas are functions, and it's very rare to have a yield in a lambda, so it seems more likely to confuse users than to help them.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, it would be good to have a separate error message for yields in comprehensions.

Copy link
Contributor Author

@alexbouayad alexbouayad Jan 23, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, done

@@ -76,11 +76,20 @@ break # E: "break" outside loop
continue # E: "continue" outside loop

[case testYieldOutsideFunction]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think all the yield/yield from cases can go in a single test case. Having more test cases hurts the performance of the test suite.

Also, could you test some more cases:

  • yield in the outermost comprehension (which is valid, because it's executed in the enclosing function's scope)
  • yield in an inner comprehension or in the if clause

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added tests -- is that what you had in mind?

@@ -217,7 +217,7 @@ def f() -> None: pass
[out]

[case testCannotIgnoreBlockingError]
yield # type: ignore # E: "yield" outside function
yield # type: ignore # E: 'yield' outside function
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're actually trying to standardize on double quotes in error messages. I believe it gets highlighted better.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, changed back to double quotes

Copy link
Member

@JelleZijlstra JelleZijlstra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your contribution!

@JelleZijlstra JelleZijlstra merged commit 619d9bd into python:master Jan 24, 2022
@alexbouayad alexbouayad deleted the fix-yield-in-comprehension branch January 24, 2022 00:41
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

Successfully merging this pull request may close these issues.

crash with generator in list comprehension
2 participants