Skip to content

Commit 773c41a

Browse files
authored
more docs
1 parent a9addfe commit 773c41a

File tree

1 file changed

+59
-9
lines changed

1 file changed

+59
-9
lines changed

Diff for: src/interop/rust_from_python.md

+59-9
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,8 @@ fn cached_answer() -> i32 {
6868
}
6969
```
7070

71-
## Valid Arguments
72-
73-
Every return value must be convertible to PyResult. This is defined as IntoPyResult trait. So any return value of them must implement IntoPyResult. It will be PyResult<PyObjectRef>, PyObjectRef and any PyResult<T> when T implements IntoPyObject. Practically we can list them like:
74-
75-
76-
The `vm` paramter is just suffix. We add it as the last parameter unless we don't use `vm` at all - very rare case. It takes an object `obj` as `PyObjectRef`, which is a general python object. It returns `PyResult<String>`, which will turn into `PyResult<PyObjectRef>` the same representation of `PyResult`.
77-
78-
Every return value must be convertible to `PyResult`. This is defined as `IntoPyResult` trait. So any return value of them must implement `IntoPyResult`. It will be `PyResult<PyObjectRef>`, `PyObjectRef` and any `PyResult<T>` when T implements `IntoPyObject`. Practically we can list them like:
71+
## Valid Arguments/Return Types
72+
Every input and return value must be convertible to `PyResult`. This is defined as `IntoPyResult` trait. So any return value of them must implement `IntoPyResult`. It will be `PyResult<PyObjectRef>`, `PyObjectRef` and any `PyResult<T>` when T implements `IntoPyObject`. Practically we can list them like:
7973
- Any `T` when `PyResult<T>` is possible
8074
- `PyObjectRef`
8175
- `PyResult<()>` and `()` as `None`
@@ -85,7 +79,63 @@ Every return value must be convertible to `PyResult`. This is defined as `IntoPy
8579
- `String` for `PyStr`
8680
- And more types implementing `IntoPyObject`.
8781

88-
The same could mostly be said about input arguments.
82+
The `vm` paramter is optional. We add it as the last parameter unless we don't use `vm` at all - very rare case. It takes an object `obj` as `PyObjectRef`, which is a general python object. It returns `PyResult<String>`, which will turn into `PyResult<PyObjectRef>` the same representation of `PyResult`. The `vm` parameter does not need to be passed in by the python code.
83+
84+
If needed a seperate struct can be used for arguments using the `FromArgs` trait like so:
85+
86+
```rust
87+
#[derive(FromArgs)]
88+
struct BisectArgs {
89+
a: PyObjectRef,
90+
x: PyObjectRef
91+
#[pyarg(any, optional)]
92+
lo: OptionalArg<ArgIndex>,
93+
#[pyarg(any, optional)]
94+
hi: OptionalArg<ArgIndex>,
95+
#[pyarg(named, default)]
96+
key: Option<PyObjectRef>,
97+
}
98+
99+
#[pyfunction]
100+
fn bisect_left(
101+
BisectArgs { a, x, lo, hi, key }: BisectArgs,
102+
vm: &VirtualMachine,
103+
) -> PyResult<usize> {
104+
// ...
105+
}
106+
107+
// or ...
108+
109+
#[pyfunction]
110+
fn bisect_left(
111+
args: BisectArgs,
112+
vm: &VirtualMachine,
113+
) -> PyResult<usize> {
114+
// ...
115+
}
116+
```
117+
118+
## Errors
119+
120+
Returning a PyResult is the supported error handling strategy. Builtin python errors are created with `vm.new_xxx_error` methods.
121+
122+
### Custom Errors
123+
124+
```
125+
#[pyattr(once)]
126+
fn error(vm: &VirtualMachine) -> PyTypeRef {
127+
vm.ctx.new_exception_type(
128+
"<module_name>",
129+
"<error_name>",
130+
Some(vec![vm.ctx.exceptions.exception_type.to_owned()]),
131+
)
132+
}
133+
134+
// convenience function
135+
fn new_error(message: &str, vm: &VirtualMachine) -> PyBaseExceptionRef {
136+
vm.new_exception_msg(vm.class("<module_name>", "<error_name>"), message.to_owned())
137+
}
138+
```
89139

90140
## Functions
91141
Functions are defined using the `#[pyfunction]` attribute.

0 commit comments

Comments
 (0)