-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New message use-yield-from
#9419
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
New message use-yield-from
#9419
Conversation
|
I may be missing some test cases and also wonder what the appropriate confidence level should be. I don't think it should be UNDEFINED. Any review is appreciated. |
|
Pierre-Sassoulas
left a comment
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.
Looks great, thank you ! The two new messages in pylint make sense and are not false positives. I think we need to fix those two violations and fix the tests to be able to run the primer and see how it fares on more diverse python projects (we do not run the primer if other tests fails).
|
So I think unit tests should be fixed. Also found some cases I had not considered and improved the checker in general. Still I think I need to do a little bit more work to handle cases like: for item in [1, 2, 3]:
yield item |
|
Also realized I need to add a docs section for the message. Will work on that as well. |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #9419 +/- ##
=======================================
Coverage 95.80% 95.81%
=======================================
Files 173 173
Lines 18776 18788 +12
=======================================
+ Hits 17989 18001 +12
Misses 787 787
|
|
I tried to add more logic to obtain a human-friendly name for other sort of iterators in emitted messages but I thought the simplicity of simply not showing it outweighed the extra-code, after all the documentation good/bad examples make it very clear and it is not a very complex message (IMO). Therefore the message now just suggests Also, I ran my branch over pylint source code and it did not emit use-yield-from messages. Maybe I am missing something? Or what were the two errors that were mentioned? |
DanielNoord
left a comment
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.
Very nice! One last nit.
| @@ -0,0 +1,39 @@ | |||
| # pylint: disable=missing-docstring, import-error | |||
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.
Could you add
| # pylint: disable=missing-docstring, import-error | |
| yield 1 |
Although it is a syntax error I would like to check that pylint doesn't crash on it.
Pierre-Sassoulas
left a comment
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.
Looks great, the coverage and primers aren't working though. Could you try to rebase on upstream main ?
doc/user_guide/checkers/features.rst
Outdated
| Emitted when a boolean condition can be simplified to a constant value. | ||
| :simplify-boolean-expression (R1709): *Boolean expression may be simplified to %s* | ||
| Emitted when redundant pre-python 2.5 ternary syntax is used. | ||
| :use-yield-from (R1737): *Consider directly using 'yield from' instead* |
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.
We have a distinction between "use" and "consider using", we should not mix both. Is there something to consider or is using yield from always better ?
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.
This check should only emit messages on very clear cases like this one:
for x in gen:
yield xAnd in those cases I think yield from is always better. I see this message as similar to use-dict-literal.
It's because there hasn't been a commit on main in five days, and all of the primer caches were evicted due to space constraints. I just manually reran the |
Damn, it's the first slow week since forever, we never encountered this issue before 😄 (it was a 'pytest' week for me). Thanks for the explanation Jacob. |
This comment has been minimized.
This comment has been minimized.
|
Looks like a FP in black. |
|
I'm not fluent with |
A new message has been added to suggest refactoring when yielding from a for loop can be replaced by 'yield from'. This message is only emitted when there are no other statements in the containing for loop. Closes pylint-dev#9229.
It is also possible to call attributes so the case has been handled regardless of the nesting level. Yield value may not always be a name as the result of function calls or other elements may be yielded, therefore nodes will be discarded if they don't yield a name.
There are too many possible generators to use in a for loop and handling all the cases to provide a human friendly display name in emitted messages seems too cumbersome compared to the benefit it brings, specially considering this message will have a doc page with examples.
The corresponding good/bad examples have been added and the message description touched up a bit.
Got to carried away deleting code and deleted the most important comparison to see if what is yielded are the items iterated on. Also added more cases to the test file.
29eb146 to
a389d3a
Compare
Good catch, I would not consider myself fluent either but in this case |
This comment has been minimized.
This comment has been minimized.
It is invalid to use 'yield from' in async functions. Replacing yielding from an 'async for' loop may not be the same as using 'yield from' so the message won't be emitted for async loops as well.
This comment has been minimized.
This comment has been minimized.
|
So I handled the async case and all primer messages seem valid to me. |
Pierre-Sassoulas
left a comment
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.
Thank you for fixing the async case, the primer looks very promising now !
| "R1737": ( | ||
| "Consider directly using 'yield from' instead", | ||
| "use-yield-from", | ||
| "Emitted when yielding from a loop can be replaced by yielding from the iterator directly.", |
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.
| "Emitted when yielding from a loop can be replaced by yielding from the iterator directly.", | |
| "yielding from a loop is slower than yielding from the iterator directly.", |
(? not sure if actually true all the time, but I suppose it's the case. At least it's going to be more elegant and understandable than the loop.)
I know almost all our messages talk about the "when" it's raised, when the "why" it's raised is a lot more interesting.
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.
Yes, I had thought about stating possible perf improvements but was not sure whether to say "possibly faster" or just state it. I guess we can go with this because it certainly won't be any slower. Besides explaining it is faster I also mentioned the cleaner code part.
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.
Sometime it's surprising, it would be better to add something in related.rst Found https://copyprogramming.com/howto/in-python-is-faster-using-yield-from-than-yield-in-a-loop it would be better if it's in depth and by someone like a python core dev but I didn't find this in a reasonable time.
|
Applied the requested changes. |
This comment has been minimized.
This comment has been minimized.
Pierre-Sassoulas
left a comment
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.
Great, thank you. Let me know what you think of the article I found for related.rst, or if you found something more convincing. This is going to be a nice addition to 3.1.0 !
|
So I could not find anything too convincing regarding the performance of I don't trust my CPython reading abilities so I can't confirm whether they have been implemented on newer versions. I did play around with As we know measuring performance is not that easy but I think we can say that |
DanielNoord
left a comment
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.
Thank you, a nice addition!
Pierre-Sassoulas
left a comment
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.
Great new checker, one of the main new features of 3.1.0 🎉
Type of Changes
Description
A new message has been added to suggest refactoring when yielding from a for loop can be replaced by 'yield from'. This message is only emitted when there are no other statements in the containing for loop.
Closes #9229.