diff --git a/guide/src/SUMMARY.md b/guide/src/SUMMARY.md index e75095f4..730f9985 100644 --- a/guide/src/SUMMARY.md +++ b/guide/src/SUMMARY.md @@ -36,9 +36,8 @@ --- [Appendix A: Migration guide](migration.md) -[Appendix B: PyO3 and rust-cpython](rust_cpython.md) -[Appendix C: Trait bounds](trait_bounds.md) -[Appendix D: Python typing hints](python_typing_hints.md) +[Appendix B: Trait bounds](trait_bounds.md) +[Appendix C: Python typing hints](python_typing_hints.md) [CHANGELOG](changelog.md) --- diff --git a/guide/src/rust_cpython.md b/guide/src/rust_cpython.md deleted file mode 100644 index 6c68d2cf..00000000 --- a/guide/src/rust_cpython.md +++ /dev/null @@ -1,82 +0,0 @@ -# PyO3 and rust-cpython - -PyO3 began as fork of [rust-cpython](https://github.com/dgrunwald/rust-cpython) when rust-cpython wasn't maintained. Over time PyO3 has become fundamentally different from rust-cpython. - -## Macros - -While rust-cpython has a `macro_rules!` based DSL for declaring modules and classes, PyO3 uses proc macros. PyO3 also doesn't change your struct and functions so you can still use them as normal Rust functions. - -**rust-cpython** - -```rust,ignore -py_class!(class MyClass |py| { - data number: i32; - def __new__(_cls, arg: i32) -> PyResult { - MyClass::create_instance(py, arg) - } - def half(&self) -> PyResult { - Ok(self.number(py) / 2) - } -}); -``` - -**PyO3** - -```rust -use pyo3::prelude::*; - -#[pyclass] -struct MyClass { - num: u32, -} - -#[pymethods] -impl MyClass { - #[new] - fn new(num: u32) -> Self { - MyClass { num } - } - - fn half(&self) -> PyResult { - Ok(self.num / 2) - } -} -``` - -## Ownership and lifetimes - -While in rust-cpython you always own Python objects, PyO3 allows efficient *borrowed objects* -and most APIs work with references. - -Here is an example of the PyList API: - -**rust-cpython** - -```rust,ignore -impl PyList { - - fn new(py: Python<'_>) -> PyList {...} - - fn get_item(&self, py: Python<'_>, index: isize) -> PyObject {...} -} -``` - -**PyO3** - -```rust,ignore -impl PyList { - - fn new(py: Python<'_>) -> &PyList {...} - - fn get_item(&self, index: isize) -> &PyAny {...} -} -``` - -In PyO3, all object references are bounded by the GIL lifetime. -So owned Python objects are not required, and it is safe to have functions like `fn py<'p>(&'p self) -> Python<'p> {}`. - -## Error handling - -rust-cpython requires a `Python` parameter for constructing a `PyErr`, so error handling ergonomics is pretty bad. It is not possible to use `?` with Rust errors. - -PyO3 on other hand does not require `Python` for constructing a `PyErr`, it is only required if you want to raise an exception in Python with the `PyErr::restore()` method. Due to various `std::convert::From for PyErr` implementations for Rust standard error types `E`, propagating `?` is supported automatically. diff --git a/src/lib.rs b/src/lib.rs index 42e2a3e8..a2e5d960 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -505,7 +505,6 @@ pub mod doc_test { "guide/src/performance.md" => guide_performance_md, "guide/src/python_from_rust.md" => guide_python_from_rust_md, "guide/src/python_typing_hints.md" => guide_python_typing_hints_md, - "guide/src/rust_cpython.md" => guide_rust_cpython_md, "guide/src/trait_bounds.md" => guide_trait_bounds_md, "guide/src/types.md" => guide_types_md, }