Pre-PEP: Rust for CPython

Note: I’m working on replying to everyone but wanted to get some initial replies out, I appreciate patience with this.

I agree with @jacopoabramo on this, I like to think that the Python community will be better about being productive, amicable, and respectful when discussing these issues. So I think the experience will be altogether different.

I reached out to David Hewitt who has now responded in this thread and will contribute to the effort (thank you, David!) . Kirill has reached out to the RustPython team as well!

On the contrary, it should be much less effort as safe Rust is thread-safe due to the borrow checker. There will need to be some support added to handle integrating attached thread states, but it should be relatively easy.

Sorry, I’m not sure if you are asking if Rust extensions will work with the JIT or if Rust can be used to implement it? For the former they should work without issue. For the latter the JIT currently relies on a custom calling convention which is not yet exposed in Rust (but is being discussed to do so last I checked). I don’t suggest moving this code to Rust until it is reasonable to implement in Rust and the necessary calling convention features are available.

This is definitely something to be cognizant of, thank you for bringing it up! There are several strategies which will not affect performance, such as abort on panic, which we can explore. We will probably want to abort on panic anyway since unwinding over FFI layers is UB.

I think this is an interesting proposal, but orthogonal to the current one. We hope Rust will eventually become required to build CPython so it can be used to improve the CPython core. I would suggest splitting this off into it’s own thread to discuss it further.

Again I think it is important to highlight that this proposal is more than just _base64, and more than just optional modules. We’d eventually like to make Rust a hard dependency so it can be used to improve the implementation of the Python runtime as well.

Thanks Alex! We definitely want to approach this carefully and with thought, your expertise will be invaluable!

I think we necessarily need to make a plan for long term adoption so we can figure out when Rust can be a required dependency and ensure we plan ahead in advance well enough for it. I don’t want to get anyone caught by surprise when suddenly they need Rust to build CPython when they don’t expect it. I will say that the final PEP will probably be what you propose plus a timeline to make Rust a required dependency. Iterating on ergonomic APIs for Rust is definitely something I’d be working on if cpython-sys is approved.

Perhaps then we can ensure that releases build with an older nightly Rust to enable such bootstrapping? I expect these cases to be relatively uncommon - Rust supports a large number of platforms.

I would restate our goal as “slowly introduce Rust to carefully integrate it and make sure we get things right and give people time to adapt to the significant change.” _base64 is chosen as an example as it is easier to implement, easier to understand, and would only affect performance, so is entirely optional. I think there are several existing modules that could see clear benefits from being written in Rust, eventually. Especially for those that interact with untrusted input such as json, it would be a significant improvement security-wise if we implemented them in a memory safe language. But I also don’t want to rush in and cause breakage. These kinds of changes should be done carefully and when well-motivated.

Good point re PyPy requiring some bootstrap Python itself! I hope that the approach of using an older CPython will be workable.

I absolutely agree, safe abstractions over things like argument parsing and module creation make PyO3 a joy to use. I hope we can collaborate with the PyO3 maintainers and provide similarly pleasant abstractions in CPython core. It will certainly be a high priority. I do think even in this simple example there are examples of safe abstractions that provide benefits. Kirill wrote up an abstraction over borrowing a Py_buffer that automatically releases the buffer on drop, so that it is impossible to forget to do that and cause a bug: cpython/Modules/_base64/src/lib.rs at c9deee600d60509c5da6ef538a9b530f7ba12e05 · emmatyping/cpython · GitHub

Thank you Guido for your trust and words of support, it really means a lot!

17 Likes