What does HackerNews think of pyo3?

Rust bindings for the Python interpreter

Language: Rust

#24 in Python
#21 in Rust
I expected someone to write a rust-based scripting language which tightly integrated with rust itself.

In reality, it seems like the python developers and toolchain are embracing rust enough to reduce the benefits to a new alternative.

https://github.com/PyO3/pyo3

You can practice your Rust skills by writing performant and/or gluey extensions for higher-level language such as NodeJS (checkout napi-rs) and Python or complementing JS in the browser if you target Webassembly.

For instance, checkout Llama-node https://github.com/Atome-FE/llama-node for an involved Rust-based NodeJS extension. Python has PyO3, a Rust-Python extension toolset: https://github.com/PyO3/pyo3.

They can help you leverage your Rust for writing cool new stuff.

(2020).

Things have arguably become even nicer (although slightly more divergent between the two) since then: Python's `Optional[T]` can now be written as `T | None`, and the core container types can now be annotated directly (e.g. `List[T]` becomes `list[T]`).

Combined via pyO3[1], Python and Rust are a real joy to write together.

[1]: https://github.com/PyO3/pyo3

It is already happening and with the availability of the tools like PyO3 [1] (it allows Python developers to write performance-critical code in Rust and then expose it as a Python module) the Rustication of the Python will be progressing while some controversies will appear [2]. Adding new language adds complexity to the python code base but it is always good to have at least choice and decide case-by-case if use Rust in Python app or not.

[1] https://github.com/PyO3/pyo3

[2] https://safjan.com/rustification-of-python/#drawbacks-and-co...

There's an entire ecosystem built up to support this. PyO3 [1] connects Rust to Python, Maturin [2] is a build tool to package Python wheels easily, with a host of popular examples using Maturn + PyO3 [3]. There's even extensions to bind easily to numpy and asyncio [4][5].

[1]: https://github.com/PyO3/pyo3

[2]: https://github.com/PyO3/maturin

[3]: https://github.com/PyO3/maturin#examples

[4]: https://github.com/PyO3/rust-numpy

[5]: https://github.com/awestlake87/pyo3-asyncio

I'd be interested in a bit more detail on the technical migration strategy. Did they just cut over to a version of the project built in Rust? (I.e. vN is Python+C/C++, vN+1 is Rust?) Or something more gradual?

How did they verify that the new code was conformant with the old app's behavior/logic?

> To make matters worse, we would discover issues only after deploying (or in production!) due to Python’s run time nature.

I don't want to infer too much, but this makes it sound like perhaps they didn't have a very robust set of E2E/Acceptance tests, which would make a full-cutover migration scary to me. If you're finding Python bugs only after deploy, how can you find the inevitable rewritten-Rust-code incompatibilities before deploying/production?

I've been digging into Rust/Python interop recently using https://github.com/PyO3/pyo3 and maturin, and this points to an interesting migration strategy; PyO3 makes it quite easy to write a Python module in Rust, or even call back and forth between them, so you could gradually move code from Python to Rust. A migration path to full-Rust might be:

1. Incrementally replace all your fast-path C/C++ code with Rust, still having Python call these compiled modules. End-state: You now have a Python/Rust project instead of Python/C/C++.

2. Gradually grow the surface area of your Rust packages, moving logic from Python into Rust. Your existing Python tests can still run, and your existing entrypoints are the same Python.

3. At some point, you presumably need to cut over the entrypoint layer (the API?) to use pure Rust, instead of Python. This should be a much less scary migration since both versions are calling into the same underlying Rust library code. Depending on your architecture, if you have an API Gateway you can split your service backends to migrate one endpoint at a time to the new Rust API service, while keeping the old Python API service around to fail back to. (They are using k8s so you can do this with your Ingress for example).

I'm interested in others' experiences with Rust/Python interop, are there any rough edges worth knowing about?

Or alternatively, PyO3 if you use Rust instead of C++: https://github.com/PyO3/pyo3
Rust is a great language for writing Python extensions, using a library like PyO3. Some of the most CPU-intensive parts of my company's feature engineering pipeline are now handled in Rust.

I would enjoy writing Rust for Python even more if I could compile and run Rust straight from the same Jupyter notebooks that I prototype my Python code with.

https://github.com/PyO3/pyo3

Yeah, it's surprising. A lot of Python people are in the community too, such as Armin, the creator of Flask.

I can't speak for Rubyists, but I find it a very strong complementary skill to Python, as it allows for writing things that are impractical in Python. And Rust feels friendlier as a Python-complement than C. Especially parallel C.

Receiving a compiler error in Rust is more appealing to me than debugging a segfault or race condition in C, especially since Rust will always tell me when one exists. Or more importantly, I can feel comfortable pushing new fast low-level code to production knowing it's not a risk. There's no ambiguity. "fearless concurrency" is not just a buzzword, it's partly what makes Rust fun and practical (for me). As well as the incredibly-fast start-up time of my Rust code compared to Python.

It is also appealing for Python programmers because of the increasingly-decent support for mixing the two languages without overhead, including publishing pure-Rust packages as python modules^1

1. https://github.com/PyO3/pyo3

> I think there's a lot of worth using a high level language and integrating with C.

I agree.

Python is an awesome high level interface to low level libraries and algorithms. As which it became even more appealing since you can write your low level code in Rust and call it from Python via PyO3 [0].

[0]: https://github.com/PyO3/pyo3

Fortunately, you don't have to use C for this any more. Rust has bindings for making extensions for Ruby, Python, Lua and Node, and generally it's very well suited for making zero-cost cleaner APIs on top of C FFI.

https://github.com/tildeio/helix https://github.com/PyO3/pyo3 https://github.com/kyren/rlua https://github.com/neon-bindings/neon

I've yet to play with beyond just experimenting a little bit, but it seems it works very well.

I've mainly been looking at these resources:

https://github.com/rochacbruno/rust-python-example

https://github.com/PyO3/pyo3

Though I have not done rust <-> python in real practice

Python extension doesn’t mean C. Rust works perfectly for extensions, it covers a lot of low level c-api integration and it is fast. You can write whole application in rust and use python as a glue language

https://github.com/PyO3/pyo3

Pyo3 library gives you ability to work both diractions. Call python code from rust and call rust code from python.