Skip to content

GH-145668: Add FOR_ITER specialization for virtual iterators. Specialize GET_ITER.#147967

Open
markshannon wants to merge 20 commits intopython:mainfrom
markshannon:specialize-iteration-with-jit
Open

GH-145668: Add FOR_ITER specialization for virtual iterators. Specialize GET_ITER.#147967
markshannon wants to merge 20 commits intopython:mainfrom
markshannon:specialize-iteration-with-jit

Conversation

@markshannon
Copy link
Copy Markdown
Member

@markshannon markshannon commented Apr 1, 2026

Add FOR_ITER specialization for virtual iterators. Specialize GET_ITER.

  • Add FOR_ITER_VIRTUAL to specialize FOR_ITER for virtual iterators
  • Add GET_ITER_SELF to specialize GET_ITER for iterators (including generators)
  • Add GET_ITER_VIRTUAL to specialize GET_ITER for iterables as virtual iterators
  • Add tp_iteritem internal slot to PyTypeObject to support a wider range of classes as virtual iterators.

This PR adds strs as virtual iterators, with the potential to add bytes, bytearray, frozenset, frozendict and others in the future.


📚 Documentation preview 📚: https://cpython-previews--147967.org.readthedocs.build/

* Add FOR_ITER_VIRTUAL to specialize FOR_ITER for virtual iterators
* Add GET_ITER_SELF to specialize GET_ITER for iterators (including generators)
* Add GET_ITER_VIRTUAL to specialize GET_ITER for iterables as virtual iterators
@Fidget-Spinner
Copy link
Copy Markdown
Member

Doesn't this change the ABI guarantees of PyTypeObject? Or are there none of those? In any case, feels strange that we are adding a public field that is opaque for our own use.

@markshannon
Copy link
Copy Markdown
Member Author

tp_watchers is already documented as internal.
The header is public, so the fields have to go in a public header even if they aren't to be used.

@markshannon markshannon requested a review from iritkatriel as a code owner April 8, 2026 16:43
Copy link
Copy Markdown
Member

@Fidget-Spinner Fidget-Spinner left a comment

Choose a reason for hiding this comment

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

A few comments

Comment thread Doc/c-api/typeobj.rst Outdated
Comment thread Include/object.h Outdated
Comment thread Python/bytecodes.c
_GUARD_ITER_VIRTUAL +
_PUSH_TAGGED_ZERO;

op(_GET_ITER_TRAD, (iterable -- iter, index_or_null)) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

what does trad mean?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Traditional

@Fidget-Spinner
Copy link
Copy Markdown
Member

Do you have benchmark numbers for this?

I'm wondering of 3 extra opcodes is worth it. I think I might have a solution for the opcode problem.

@markshannon
Copy link
Copy Markdown
Member Author

Do you have benchmark numbers for this?

In the noise. But this enables more optimizations, so neutral is good.

I'm wondering of 3 extra opcodes is worth it.

The FOR_ITER_VIRTUAL is worth it, as it allows more common iterables to be treated as virtual iterators.

By themselves, the two new GET_ITER specializations probably wouldn't be.
They're worth it because they complement the FOR_ITER and, very soon, the SEND specializations.
For those specializations to work we need GET_ITER to handle the three distinct cases:

  • Already an iterator: do nothing
  • An iterable, supporting virtual iteration: push tagged zero
  • Other iterables, call __iter__ to get the iterator

So the specializations follow naturally.

I think I might have a solution for the opcode problem.

That's good, but not directly relevant to this PR I think.
We aren't in imminent danger of running out of opcodes, provided we followed a reasonably principled approach to specializations.

Comment thread Include/object.h Outdated
Comment thread Doc/c-api/typeobj.rst Outdated
Comment thread Include/object.h Outdated
@Fidget-Spinner Fidget-Spinner added the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Apr 15, 2026
@bedevere-bot
Copy link
Copy Markdown

🤖 New build scheduled with the buildbot fleet by @Fidget-Spinner for commit a55ac63 🤖

Results will be shown at:

https://buildbot.python.org/all/#/grid?branch=refs%2Fpull%2F147967%2Fmerge

If you want to schedule another build, you need to add the 🔨 test-with-buildbots label again.

@bedevere-bot bedevere-bot removed the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Apr 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants