Skip to content

[mypyc] Fix segfault when a native __next__ returns an unboxed value - #22145

Open
rheard wants to merge 1 commit into
python:masterfrom
rheard:fix-mypyc-1235
Open

rheard wants to merge 1 commit into
python:masterfrom
rheard:fix-mypyc-1235

Conversation

@rheard

@rheard rheard commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Fixes mypyc/mypyc#1235.

native_slot() filled tp_iternext with the native __next__ method itself, which only works if the method returns PyObject *. With -> int, CPython got the tagged integer, or CPY_INT_TAG after StopIteration, as an object pointer, so next(), for loops, list() and obj.__next__() from Python all crashed. float, i64 and tuples crashed too. With bool, False came back as NULL, so the iteration stopped early without an error. MSVC warns about the mismatch (C4047).

native_slot() now uses generate_dunder_wrapper() when the method returns an unboxed value. That's the wrapper the unary number slots such as __int__ and __index__ already use. It calls the native method, returns NULL if the method raised (checking PyErr_Occurred() for types such as float, whose error value is also a valid value), and boxes the result. A StopIteration raised by __next__ still ends the iteration, because the wrapper returns NULL with it set. Methods that return an object, including the __next__ of every native generator, still fill the slot directly, so they don't get an extra call. The other slots that use native_slot() (__iter__, __str__, __repr__, __await__, __aiter__ and __anext__) get the same check, although they normally return objects.

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.

next() and for loops segfault on a native class whose __next__ returns int

1 participant