don't prefetch next item in loop context #1101
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
fixes #555
Previously,
LoopContext
prefetched the next item in the iterable, the internal iterator was advanced one further than the index. This caused issues withgroupby
or other iterators where items depend on the state of the iterator.Now, the iterator will only advance early for the
length
,revindex
,last
andnextitem
properties, using any other properties in the loop will not mess upgroupby
.Unfortunately, this couldn't carry over to
AsyncLoopContext
directly. To look ahead in async, you need toawait it.__anext__()
rather thannext(it)
. Toawait
, you need to be inasync def
, but only__anext__
is async, not the properties, and we're not prefetching during iteration anymore. So this reimplements some properties to be async. This has the extra effect of makinglength
,revindex
, andrevindex0
work for async iterables (they raised aTypeError
before). The compiler must addawait auto_await()
around attribute access for these properties to resolve, previously it was only added for calls.I feel like this implementation is cleaner overall, but I'm not sure of the implications for async performance.