remove comparison to rust-cpython
This commit is contained in:
parent
f12f928bd5
commit
2ca8e573a4
|
@ -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)
|
||||
|
||||
---
|
||||
|
|
|
@ -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> {
|
||||
MyClass::create_instance(py, arg)
|
||||
}
|
||||
def half(&self) -> PyResult<i32> {
|
||||
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<u32> {
|
||||
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<E> for PyErr` implementations for Rust standard error types `E`, propagating `?` is supported automatically.
|
|
@ -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,
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue