As someone who was involved in implementing these, I think they should not be in builtins if that means they have to be in C.

My argument is from a point of maintainability. Writing them was plenty of effort in the first place; Josh had written them in idiomatic async Python in the first place, my contribution was to unroll that to sync Python code, and then port that to (sync) C code. It was a lot of effort and a lot of code - several hundred lines and 4(?) new types. The Python code was a few lines - very readable and likely to be practically as fast. We weren't writing this in C to speed it up or to make the code better, but because we *had to*.

Implementing async functionality in C is a pain because to implement an awaitable type you need not just that awaitable type, but a new type to represent the iterator that am_await returns. I could imagine having generic type objects and other helpers for implementing async PyObjects in C but I don't really envisage anyone doing that; if you want to write async helpers for Python the best framework is Python.

As Josh can attest I was in two minds while implementing this change; I argued firstly that having them in the operator module is fine, and later, that if we want async builtins in general, maybe we could implement them in Python and freeze them into the binary. We pushed on with the C approach mostly because we were already 70% done, and this was what Yury asked for, so it seemed more likely that this would get merged.

But, if we're still discussing whether this should be merged in builtins or operator, and that dictates whether it is in Python or C, I'm 100% behind having this code be Python.