Refactor `#[pyproto]` Result types
This commit is contained in:
parent
4c04268bdb
commit
c7a4b4770f
|
@ -26,6 +26,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|||
- Update `num-bigint` optional dependendency from `0.2` to `0.3`. [#978](https://github.com/PyO3/pyo3/pull/978)
|
||||
- `#[pyproto]` is re-implemented without specialization. [#961](https://github.com/PyO3/pyo3/pull/961)
|
||||
- `PyClassAlloc::alloc` is renamed to `PyClassAlloc::new`. [#990](https://github.com/PyO3/pyo3/pull/990)
|
||||
- `#[pyproto]` methods can now have return value `T` or `PyResult<T>` (previously only `PyResult<T>` was supported). [#996](https://github.com/PyO3/pyo3/pull/996)
|
||||
|
||||
### Removed
|
||||
- Remove `ManagedPyRef` (unused, and needs specialization) [#930](https://github.com/PyO3/pyo3/pull/930)
|
||||
|
@ -34,6 +35,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|||
### Fixed
|
||||
- Fix passing explicit `None` to `Option<T>` argument `#[pyfunction]` with a default value. [#936](https://github.com/PyO3/pyo3/pull/936)
|
||||
- Fix `PyClass.__new__`'s not respecting subclasses when inherited by a Python class. [#990](https://github.com/PyO3/pyo3/pull/990)
|
||||
- Fix returning `Option<T>` from `#[pyproto]` methods. [#996](https://github.com/PyO3/pyo3/pull/996)
|
||||
|
||||
## [0.10.1] - 2020-05-14
|
||||
### Fixed
|
||||
|
|
|
@ -688,6 +688,9 @@ mapping or number protocols. PyO3 defines separate traits for each of them. To p
|
|||
Python object behavior, you need to implement the specific trait for your struct. Important note,
|
||||
each protocol implementation block has to be annotated with the `#[pyproto]` attribute.
|
||||
|
||||
All `#[pyproto]` methods which can be defined below can return `T` instead of `PyResult<T>` if the
|
||||
method implementation is infallible.
|
||||
|
||||
### Basic object customization
|
||||
|
||||
The [`PyObjectProtocol`] trait provides several basic customizations.
|
||||
|
@ -823,11 +826,11 @@ struct MyIterator {
|
|||
|
||||
#[pyproto]
|
||||
impl PyIterProtocol for MyIterator {
|
||||
fn __iter__(slf: PyRef<Self>) -> PyResult<Py<MyIterator>> {
|
||||
Ok(slf.into())
|
||||
fn __iter__(slf: PyRef<Self>) -> Py<MyIterator> {
|
||||
slf.into()
|
||||
}
|
||||
fn __next__(mut slf: PyRefMut<Self>) -> PyResult<Option<PyObject>> {
|
||||
Ok(slf.iter.next())
|
||||
fn __next__(mut slf: PyRefMut<Self>) -> Option<PyObject> {
|
||||
slf.iter.next()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
@ -848,12 +851,12 @@ struct Iter {
|
|||
|
||||
#[pyproto]
|
||||
impl PyIterProtocol for Iter {
|
||||
fn __iter__(slf: PyRefMut<Self>) -> PyResult<Py<Iter>> {
|
||||
Ok(slf.into())
|
||||
fn __iter__(slf: PyRefMut<Self>) -> Py<Iter> {
|
||||
slf.into()
|
||||
}
|
||||
|
||||
fn __next__(mut slf: PyRefMut<Self>) -> PyResult<Option<usize>> {
|
||||
Ok(slf.inner.next())
|
||||
fn __next__(mut slf: PyRefMut<Self>) -> Option<usize> {
|
||||
slf.inner.next()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -868,7 +871,7 @@ impl PyIterProtocol for Container {
|
|||
let iter = Iter {
|
||||
inner: slf.iter.clone().into_iter(),
|
||||
};
|
||||
PyCell::new(slf.py(), iter).map(Into::into)
|
||||
Py::new(slf.py(), iter)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -89,57 +89,47 @@ pub const OBJECT: Proto = Proto {
|
|||
MethodProto::Binary {
|
||||
name: "__getattr__",
|
||||
arg: "Name",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::basic::PyObjectGetAttrProtocol",
|
||||
},
|
||||
MethodProto::Ternary {
|
||||
name: "__setattr__",
|
||||
arg1: "Name",
|
||||
arg2: "Value",
|
||||
pyres: false,
|
||||
proto: "pyo3::class::basic::PyObjectSetAttrProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__delattr__",
|
||||
arg: "Name",
|
||||
pyres: false,
|
||||
proto: "pyo3::class::basic::PyObjectDelAttrProtocol",
|
||||
},
|
||||
MethodProto::Unary {
|
||||
name: "__str__",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::basic::PyObjectStrProtocol",
|
||||
},
|
||||
MethodProto::Unary {
|
||||
name: "__repr__",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::basic::PyObjectReprProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__format__",
|
||||
arg: "Format",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::basic::PyObjectFormatProtocol",
|
||||
},
|
||||
MethodProto::Unary {
|
||||
name: "__hash__",
|
||||
pyres: false,
|
||||
proto: "pyo3::class::basic::PyObjectHashProtocol",
|
||||
},
|
||||
MethodProto::Unary {
|
||||
name: "__bytes__",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::basic::PyObjectBytesProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__richcmp__",
|
||||
arg: "Other",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::basic::PyObjectRichcmpProtocol",
|
||||
},
|
||||
MethodProto::Unary {
|
||||
name: "__bool__",
|
||||
pyres: false,
|
||||
proto: "pyo3::class::basic::PyObjectBoolProtocol",
|
||||
},
|
||||
],
|
||||
|
@ -173,24 +163,20 @@ pub const ASYNC: Proto = Proto {
|
|||
MethodProto::UnaryS {
|
||||
name: "__await__",
|
||||
arg: "Receiver",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::pyasync::PyAsyncAwaitProtocol",
|
||||
},
|
||||
MethodProto::UnaryS {
|
||||
name: "__aiter__",
|
||||
arg: "Receiver",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::pyasync::PyAsyncAiterProtocol",
|
||||
},
|
||||
MethodProto::UnaryS {
|
||||
name: "__anext__",
|
||||
arg: "Receiver",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::pyasync::PyAsyncAnextProtocol",
|
||||
},
|
||||
MethodProto::Unary {
|
||||
name: "__aenter__",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::pyasync::PyAsyncAenterProtocol",
|
||||
},
|
||||
MethodProto::Quaternary {
|
||||
|
@ -225,12 +211,10 @@ pub const BUFFER: Proto = Proto {
|
|||
methods: &[
|
||||
MethodProto::Unary {
|
||||
name: "bf_getbuffer",
|
||||
pyres: false,
|
||||
proto: "pyo3::class::buffer::PyBufferGetBufferProtocol",
|
||||
},
|
||||
MethodProto::Unary {
|
||||
name: "bf_releasebuffer",
|
||||
pyres: false,
|
||||
proto: "pyo3::class::buffer::PyBufferReleaseBufferProtocol",
|
||||
},
|
||||
],
|
||||
|
@ -248,7 +232,6 @@ pub const CONTEXT: Proto = Proto {
|
|||
methods: &[
|
||||
MethodProto::Unary {
|
||||
name: "__enter__",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::context::PyContextEnterProtocol",
|
||||
},
|
||||
MethodProto::Quaternary {
|
||||
|
@ -303,7 +286,6 @@ pub const DESCR: Proto = Proto {
|
|||
arg1: "Receiver",
|
||||
arg2: "Inst",
|
||||
arg3: "Owner",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::descr::PyDescrGetProtocol",
|
||||
},
|
||||
MethodProto::TernaryS {
|
||||
|
@ -311,19 +293,16 @@ pub const DESCR: Proto = Proto {
|
|||
arg1: "Receiver",
|
||||
arg2: "Inst",
|
||||
arg3: "Value",
|
||||
pyres: false,
|
||||
proto: "pyo3::class::descr::PyDescrSetProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__det__",
|
||||
arg: "Inst",
|
||||
pyres: false,
|
||||
proto: "pyo3::class::descr::PyDescrDelProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__set_name__",
|
||||
arg: "Inst",
|
||||
pyres: false,
|
||||
proto: "pyo3::class::descr::PyDescrSetNameProtocol",
|
||||
},
|
||||
],
|
||||
|
@ -349,13 +328,11 @@ pub const ITER: Proto = Proto {
|
|||
MethodProto::UnaryS {
|
||||
name: "__iter__",
|
||||
arg: "Receiver",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::iter::PyIterIterProtocol",
|
||||
},
|
||||
MethodProto::UnaryS {
|
||||
name: "__next__",
|
||||
arg: "Receiver",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::iter::PyIterNextProtocol",
|
||||
},
|
||||
],
|
||||
|
@ -372,31 +349,26 @@ pub const MAPPING: Proto = Proto {
|
|||
methods: &[
|
||||
MethodProto::Unary {
|
||||
name: "__len__",
|
||||
pyres: false,
|
||||
proto: "pyo3::class::mapping::PyMappingLenProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__getitem__",
|
||||
arg: "Key",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::mapping::PyMappingGetItemProtocol",
|
||||
},
|
||||
MethodProto::Ternary {
|
||||
name: "__setitem__",
|
||||
arg1: "Key",
|
||||
arg2: "Value",
|
||||
pyres: false,
|
||||
proto: "pyo3::class::mapping::PyMappingSetItemProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__delitem__",
|
||||
arg: "Key",
|
||||
pyres: false,
|
||||
proto: "pyo3::class::mapping::PyMappingDelItemProtocol",
|
||||
},
|
||||
MethodProto::Unary {
|
||||
name: "__reversed__",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::mapping::PyMappingReversedProtocol",
|
||||
},
|
||||
],
|
||||
|
@ -424,56 +396,47 @@ pub const SEQ: Proto = Proto {
|
|||
methods: &[
|
||||
MethodProto::Unary {
|
||||
name: "__len__",
|
||||
pyres: false,
|
||||
proto: "pyo3::class::sequence::PySequenceLenProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__getitem__",
|
||||
arg: "Index",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::sequence::PySequenceGetItemProtocol",
|
||||
},
|
||||
MethodProto::Ternary {
|
||||
name: "__setitem__",
|
||||
arg1: "Index",
|
||||
arg2: "Value",
|
||||
pyres: false,
|
||||
proto: "pyo3::class::sequence::PySequenceSetItemProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__delitem__",
|
||||
arg: "Index",
|
||||
pyres: false,
|
||||
proto: "pyo3::class::sequence::PySequenceDelItemProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__contains__",
|
||||
arg: "Item",
|
||||
pyres: false,
|
||||
proto: "pyo3::class::sequence::PySequenceContainsProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__concat__",
|
||||
arg: "Other",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::sequence::PySequenceConcatProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__repeat__",
|
||||
arg: "Index",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::sequence::PySequenceRepeatProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__inplace_concat__",
|
||||
arg: "Other",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::sequence::PySequenceInplaceConcatProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__inplace_repeat__",
|
||||
arg: "Index",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::sequence::PySequenceInplaceRepeatProtocol",
|
||||
},
|
||||
],
|
||||
|
@ -505,56 +468,48 @@ pub const NUM: Proto = Proto {
|
|||
name: "__add__",
|
||||
arg1: "Left",
|
||||
arg2: "Right",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::number::PyNumberAddProtocol",
|
||||
},
|
||||
MethodProto::BinaryS {
|
||||
name: "__sub__",
|
||||
arg1: "Left",
|
||||
arg2: "Right",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::number::PyNumberSubProtocol",
|
||||
},
|
||||
MethodProto::BinaryS {
|
||||
name: "__mul__",
|
||||
arg1: "Left",
|
||||
arg2: "Right",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::number::PyNumberMulProtocol",
|
||||
},
|
||||
MethodProto::BinaryS {
|
||||
name: "__matmul__",
|
||||
arg1: "Left",
|
||||
arg2: "Right",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::number::PyNumberMatmulProtocol",
|
||||
},
|
||||
MethodProto::BinaryS {
|
||||
name: "__truediv__",
|
||||
arg1: "Left",
|
||||
arg2: "Right",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::number::PyNumberTruedivProtocol",
|
||||
},
|
||||
MethodProto::BinaryS {
|
||||
name: "__floordiv__",
|
||||
arg1: "Left",
|
||||
arg2: "Right",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::number::PyNumberFloordivProtocol",
|
||||
},
|
||||
MethodProto::BinaryS {
|
||||
name: "__mod__",
|
||||
arg1: "Left",
|
||||
arg2: "Right",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::number::PyNumberModProtocol",
|
||||
},
|
||||
MethodProto::BinaryS {
|
||||
name: "__divmod__",
|
||||
arg1: "Left",
|
||||
arg2: "Right",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::number::PyNumberDivmodProtocol",
|
||||
},
|
||||
MethodProto::TernaryS {
|
||||
|
@ -562,251 +517,209 @@ pub const NUM: Proto = Proto {
|
|||
arg1: "Left",
|
||||
arg2: "Right",
|
||||
arg3: "Modulo",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::number::PyNumberPowProtocol",
|
||||
},
|
||||
MethodProto::BinaryS {
|
||||
name: "__lshift__",
|
||||
arg1: "Left",
|
||||
arg2: "Right",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::number::PyNumberLShiftProtocol",
|
||||
},
|
||||
MethodProto::BinaryS {
|
||||
name: "__rshift__",
|
||||
arg1: "Left",
|
||||
arg2: "Right",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::number::PyNumberRShiftProtocol",
|
||||
},
|
||||
MethodProto::BinaryS {
|
||||
name: "__and__",
|
||||
arg1: "Left",
|
||||
arg2: "Right",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::number::PyNumberAndProtocol",
|
||||
},
|
||||
MethodProto::BinaryS {
|
||||
name: "__xor__",
|
||||
arg1: "Left",
|
||||
arg2: "Right",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::number::PyNumberXorProtocol",
|
||||
},
|
||||
MethodProto::BinaryS {
|
||||
name: "__or__",
|
||||
arg1: "Left",
|
||||
arg2: "Right",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::number::PyNumberOrProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__radd__",
|
||||
arg: "Other",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::number::PyNumberRAddProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__rsub__",
|
||||
arg: "Other",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::number::PyNumberRSubProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__rmul__",
|
||||
arg: "Other",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::number::PyNumberRMulProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__rmatmul__",
|
||||
arg: "Other",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::number::PyNumberRMatmulProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__rtruediv__",
|
||||
arg: "Other",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::number::PyNumberRTruedivProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__rfloordiv__",
|
||||
arg: "Other",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::number::PyNumberRFloordivProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__rmod__",
|
||||
arg: "Other",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::number::PyNumberRModProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__rdivmod__",
|
||||
arg: "Other",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::number::PyNumberRDivmodProtocol",
|
||||
},
|
||||
MethodProto::Ternary {
|
||||
name: "__rpow__",
|
||||
arg1: "Other",
|
||||
arg2: "Modulo",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::number::PyNumberRPowProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__rlshift__",
|
||||
arg: "Other",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::number::PyNumberRLShiftProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__rrshift__",
|
||||
arg: "Other",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::number::PyNumberRRShiftProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__rand__",
|
||||
arg: "Other",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::number::PyNumberRAndProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__rxor__",
|
||||
arg: "Other",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::number::PyNumberRXorProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__ror__",
|
||||
arg: "Other",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::number::PyNumberROrProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__iadd__",
|
||||
arg: "Other",
|
||||
pyres: false,
|
||||
proto: "pyo3::class::number::PyNumberIAddProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__isub__",
|
||||
arg: "Other",
|
||||
pyres: false,
|
||||
proto: "pyo3::class::number::PyNumberISubProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__imul__",
|
||||
arg: "Other",
|
||||
pyres: false,
|
||||
proto: "pyo3::class::number::PyNumberIMulProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__imatmul__",
|
||||
arg: "Other",
|
||||
pyres: false,
|
||||
proto: "pyo3::class::number::PyNumberIMatmulProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__itruediv__",
|
||||
arg: "Other",
|
||||
pyres: false,
|
||||
proto: "pyo3::class::number::PyNumberITruedivProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__ifloordiv__",
|
||||
arg: "Other",
|
||||
pyres: false,
|
||||
proto: "pyo3::class::number::PyNumberIFloordivProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__imod__",
|
||||
arg: "Other",
|
||||
pyres: false,
|
||||
proto: "pyo3::class::number::PyNumberIModProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__ipow__",
|
||||
arg: "Other",
|
||||
pyres: false,
|
||||
proto: "pyo3::class::number::PyNumberIPowProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__ilshift__",
|
||||
arg: "Other",
|
||||
pyres: false,
|
||||
proto: "pyo3::class::number::PyNumberILShiftProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__irshift__",
|
||||
arg: "Other",
|
||||
pyres: false,
|
||||
proto: "pyo3::class::number::PyNumberIRShiftProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__iand__",
|
||||
arg: "Other",
|
||||
pyres: false,
|
||||
proto: "pyo3::class::number::PyNumberIAndProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__ixor__",
|
||||
arg: "Other",
|
||||
pyres: false,
|
||||
proto: "pyo3::class::number::PyNumberIXorProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__ior__",
|
||||
arg: "Other",
|
||||
pyres: false,
|
||||
proto: "pyo3::class::number::PyNumberIOrProtocol",
|
||||
},
|
||||
MethodProto::Unary {
|
||||
name: "__neg__",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::number::PyNumberNegProtocol",
|
||||
},
|
||||
MethodProto::Unary {
|
||||
name: "__pos__",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::number::PyNumberPosProtocol",
|
||||
},
|
||||
MethodProto::Unary {
|
||||
name: "__abs__",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::number::PyNumberAbsProtocol",
|
||||
},
|
||||
MethodProto::Unary {
|
||||
name: "__invert__",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::number::PyNumberInvertProtocol",
|
||||
},
|
||||
MethodProto::Unary {
|
||||
name: "__complex__",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::number::PyNumberComplexProtocol",
|
||||
},
|
||||
MethodProto::Unary {
|
||||
name: "__int__",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::number::PyNumberIntProtocol",
|
||||
},
|
||||
MethodProto::Unary {
|
||||
name: "__float__",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::number::PyNumberFloatProtocol",
|
||||
},
|
||||
MethodProto::Unary {
|
||||
name: "__index__",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::number::PyNumberIndexProtocol",
|
||||
},
|
||||
MethodProto::Binary {
|
||||
name: "__round__",
|
||||
arg: "NDigits",
|
||||
pyres: true,
|
||||
proto: "pyo3::class::number::PyNumberRoundProtocol",
|
||||
},
|
||||
],
|
||||
|
|
|
@ -15,33 +15,28 @@ pub enum MethodProto {
|
|||
},
|
||||
Unary {
|
||||
name: &'static str,
|
||||
pyres: bool,
|
||||
proto: &'static str,
|
||||
},
|
||||
UnaryS {
|
||||
name: &'static str,
|
||||
arg: &'static str,
|
||||
pyres: bool,
|
||||
proto: &'static str,
|
||||
},
|
||||
Binary {
|
||||
name: &'static str,
|
||||
arg: &'static str,
|
||||
pyres: bool,
|
||||
proto: &'static str,
|
||||
},
|
||||
BinaryS {
|
||||
name: &'static str,
|
||||
arg1: &'static str,
|
||||
arg2: &'static str,
|
||||
pyres: bool,
|
||||
proto: &'static str,
|
||||
},
|
||||
Ternary {
|
||||
name: &'static str,
|
||||
arg1: &'static str,
|
||||
arg2: &'static str,
|
||||
pyres: bool,
|
||||
proto: &'static str,
|
||||
},
|
||||
TernaryS {
|
||||
|
@ -49,7 +44,6 @@ pub enum MethodProto {
|
|||
arg1: &'static str,
|
||||
arg2: &'static str,
|
||||
arg3: &'static str,
|
||||
pyres: bool,
|
||||
proto: &'static str,
|
||||
},
|
||||
Quaternary {
|
||||
|
@ -88,7 +82,7 @@ pub(crate) fn impl_method_proto(
|
|||
};
|
||||
}
|
||||
|
||||
let ty = &*if let syn::ReturnType::Type(_, ref ty) = sig.output {
|
||||
let ret_ty = &*if let syn::ReturnType::Type(_, ref ty) = sig.output {
|
||||
ty.clone()
|
||||
} else {
|
||||
panic!("fn return type is not supported")
|
||||
|
@ -96,9 +90,8 @@ pub(crate) fn impl_method_proto(
|
|||
|
||||
match *meth {
|
||||
MethodProto::Free { .. } => unreachable!(),
|
||||
MethodProto::Unary { pyres, proto, .. } => {
|
||||
MethodProto::Unary { proto, .. } => {
|
||||
let p: syn::Path = syn::parse_str(proto).unwrap();
|
||||
let (ty, succ) = get_res_success(ty);
|
||||
|
||||
let tmp: syn::ItemFn = syn::parse_quote! {
|
||||
fn test(&self) -> <#cls as #p<'p>>::Result {}
|
||||
|
@ -106,26 +99,14 @@ pub(crate) fn impl_method_proto(
|
|||
sig.output = tmp.sig.output;
|
||||
modify_self_ty(sig);
|
||||
|
||||
if pyres {
|
||||
quote! {
|
||||
impl<'p> #p<'p> for #cls {
|
||||
type Success = #succ;
|
||||
type Result = #ty;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
impl<'p> #p<'p> for #cls {
|
||||
type Result = #ty;
|
||||
}
|
||||
quote! {
|
||||
impl<'p> #p<'p> for #cls {
|
||||
type Result = #ret_ty;
|
||||
}
|
||||
}
|
||||
}
|
||||
MethodProto::UnaryS {
|
||||
pyres, proto, arg, ..
|
||||
} => {
|
||||
MethodProto::UnaryS { proto, arg, .. } => {
|
||||
let p: syn::Path = syn::parse_str(proto).unwrap();
|
||||
let (ty, succ) = get_res_success(ty);
|
||||
|
||||
let slf_name = syn::Ident::new(arg, Span::call_site());
|
||||
let mut slf_ty = get_arg_ty(sig, 0);
|
||||
|
@ -156,29 +137,14 @@ pub(crate) fn impl_method_proto(
|
|||
});
|
||||
}
|
||||
|
||||
if pyres {
|
||||
quote! {
|
||||
impl<'p> #p<'p> for #cls {
|
||||
type #slf_name = #slf_ty;
|
||||
type Success = #succ;
|
||||
type Result = #ty;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
impl<'p> #p<'p> for #cls {
|
||||
type #slf_name = #slf_ty;
|
||||
type Result = #ty;
|
||||
}
|
||||
quote! {
|
||||
impl<'p> #p<'p> for #cls {
|
||||
type #slf_name = #slf_ty;
|
||||
type Result = #ret_ty;
|
||||
}
|
||||
}
|
||||
}
|
||||
MethodProto::Binary {
|
||||
name,
|
||||
arg,
|
||||
pyres,
|
||||
proto,
|
||||
} => {
|
||||
MethodProto::Binary { name, arg, proto } => {
|
||||
if sig.inputs.len() <= 1 {
|
||||
println!("Not enough arguments for {}", name);
|
||||
return TokenStream::new();
|
||||
|
@ -187,7 +153,6 @@ pub(crate) fn impl_method_proto(
|
|||
let p: syn::Path = syn::parse_str(proto).unwrap();
|
||||
let arg_name = syn::Ident::new(arg, Span::call_site());
|
||||
let arg_ty = get_arg_ty(sig, 1);
|
||||
let (ty, succ) = get_res_success(ty);
|
||||
|
||||
let tmp = extract_decl(syn::parse_quote! {
|
||||
fn test(&self,arg: <#cls as #p<'p>>::#arg_name)-> <#cls as #p<'p>>::Result {}
|
||||
|
@ -200,20 +165,10 @@ pub(crate) fn impl_method_proto(
|
|||
modify_arg_ty(sig, 1, &tmp, &tmp2);
|
||||
modify_self_ty(sig);
|
||||
|
||||
if pyres {
|
||||
quote! {
|
||||
impl<'p> #p<'p> for #cls {
|
||||
type #arg_name = #arg_ty;
|
||||
type Success = #succ;
|
||||
type Result = #ty;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
impl<'p> #p<'p> for #cls {
|
||||
type #arg_name = #arg_ty;
|
||||
type Result = #ty;
|
||||
}
|
||||
quote! {
|
||||
impl<'p> #p<'p> for #cls {
|
||||
type #arg_name = #arg_ty;
|
||||
type Result = #ret_ty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -221,7 +176,6 @@ pub(crate) fn impl_method_proto(
|
|||
name,
|
||||
arg1,
|
||||
arg2,
|
||||
pyres,
|
||||
proto,
|
||||
} => {
|
||||
if sig.inputs.len() <= 1 {
|
||||
|
@ -233,7 +187,6 @@ pub(crate) fn impl_method_proto(
|
|||
let arg1_ty = get_arg_ty(sig, 0);
|
||||
let arg2_name = syn::Ident::new(arg2, Span::call_site());
|
||||
let arg2_ty = get_arg_ty(sig, 1);
|
||||
let (ty, succ) = get_res_success(ty);
|
||||
|
||||
// rewrite ty
|
||||
let tmp = extract_decl(syn::parse_quote! {fn test(
|
||||
|
@ -247,22 +200,11 @@ pub(crate) fn impl_method_proto(
|
|||
modify_arg_ty(sig, 0, &tmp, &tmp2);
|
||||
modify_arg_ty(sig, 1, &tmp, &tmp2);
|
||||
|
||||
if pyres {
|
||||
quote! {
|
||||
impl<'p> #p<'p> for #cls {
|
||||
type #arg1_name = #arg1_ty;
|
||||
type #arg2_name = #arg2_ty;
|
||||
type Success = #succ;
|
||||
type Result = #ty;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
impl<'p> #p<'p> for #cls {
|
||||
type #arg1_name = #arg1_ty;
|
||||
type #arg2_name = #arg2_ty;
|
||||
type Result = #ty;
|
||||
}
|
||||
quote! {
|
||||
impl<'p> #p<'p> for #cls {
|
||||
type #arg1_name = #arg1_ty;
|
||||
type #arg2_name = #arg2_ty;
|
||||
type Result = #ret_ty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -270,7 +212,6 @@ pub(crate) fn impl_method_proto(
|
|||
name,
|
||||
arg1,
|
||||
arg2,
|
||||
pyres,
|
||||
proto,
|
||||
} => {
|
||||
if sig.inputs.len() <= 2 {
|
||||
|
@ -282,7 +223,6 @@ pub(crate) fn impl_method_proto(
|
|||
let arg1_ty = get_arg_ty(sig, 1);
|
||||
let arg2_name = syn::Ident::new(arg2, Span::call_site());
|
||||
let arg2_ty = get_arg_ty(sig, 2);
|
||||
let (ty, succ) = get_res_success(ty);
|
||||
|
||||
// rewrite ty
|
||||
let tmp = extract_decl(syn::parse_quote! {fn test(
|
||||
|
@ -299,22 +239,11 @@ pub(crate) fn impl_method_proto(
|
|||
modify_arg_ty(sig, 2, &tmp, &tmp2);
|
||||
modify_self_ty(sig);
|
||||
|
||||
if pyres {
|
||||
quote! {
|
||||
impl<'p> #p<'p> for #cls {
|
||||
type #arg1_name = #arg1_ty;
|
||||
type #arg2_name = #arg2_ty;
|
||||
type Success = #succ;
|
||||
type Result = #ty;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
impl<'p> #p<'p> for #cls {
|
||||
type #arg1_name = #arg1_ty;
|
||||
type #arg2_name = #arg2_ty;
|
||||
type Result = #ty;
|
||||
}
|
||||
quote! {
|
||||
impl<'p> #p<'p> for #cls {
|
||||
type #arg1_name = #arg1_ty;
|
||||
type #arg2_name = #arg2_ty;
|
||||
type Result = #ret_ty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -323,7 +252,6 @@ pub(crate) fn impl_method_proto(
|
|||
arg1,
|
||||
arg2,
|
||||
arg3,
|
||||
pyres,
|
||||
proto,
|
||||
} => {
|
||||
if sig.inputs.len() <= 2 {
|
||||
|
@ -337,7 +265,6 @@ pub(crate) fn impl_method_proto(
|
|||
let arg2_ty = get_arg_ty(sig, 1);
|
||||
let arg3_name = syn::Ident::new(arg3, Span::call_site());
|
||||
let arg3_ty = get_arg_ty(sig, 2);
|
||||
let (ty, succ) = get_res_success(ty);
|
||||
|
||||
// rewrite ty
|
||||
let tmp = extract_decl(syn::parse_quote! {fn test(
|
||||
|
@ -354,24 +281,12 @@ pub(crate) fn impl_method_proto(
|
|||
modify_arg_ty(sig, 1, &tmp, &tmp2);
|
||||
modify_arg_ty(sig, 2, &tmp, &tmp2);
|
||||
|
||||
if pyres {
|
||||
quote! {
|
||||
impl<'p> #p<'p> for #cls {
|
||||
type #arg1_name = #arg1_ty;
|
||||
type #arg2_name = #arg2_ty;
|
||||
type #arg3_name = #arg3_ty;
|
||||
type Success = #succ;
|
||||
type Result = #ty;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
impl<'p> #p<'p> for #cls {
|
||||
type #arg1_name = #arg1_ty;
|
||||
type #arg2_name = #arg2_ty;
|
||||
type #arg3_name = #arg3_ty;
|
||||
type Result = #ty;
|
||||
}
|
||||
quote! {
|
||||
impl<'p> #p<'p> for #cls {
|
||||
type #arg1_name = #arg1_ty;
|
||||
type #arg2_name = #arg2_ty;
|
||||
type #arg3_name = #arg3_ty;
|
||||
type Result = #ret_ty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -393,7 +308,6 @@ pub(crate) fn impl_method_proto(
|
|||
let arg2_ty = get_arg_ty(sig, 2);
|
||||
let arg3_name = syn::Ident::new(arg3, Span::call_site());
|
||||
let arg3_ty = get_arg_ty(sig, 3);
|
||||
let (ty, succ) = get_res_success(ty);
|
||||
|
||||
// rewrite ty
|
||||
let tmp = extract_decl(syn::parse_quote! {fn test(
|
||||
|
@ -418,8 +332,7 @@ pub(crate) fn impl_method_proto(
|
|||
type #arg1_name = #arg1_ty;
|
||||
type #arg2_name = #arg2_ty;
|
||||
type #arg3_name = #arg3_ty;
|
||||
type Success = #succ;
|
||||
type Result = #ty;
|
||||
type Result = #ret_ty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -460,62 +373,6 @@ fn get_arg_ty(sig: &syn::Signature, idx: usize) -> syn::Type {
|
|||
ty
|
||||
}
|
||||
|
||||
// Success
|
||||
fn get_res_success(ty: &syn::Type) -> (TokenStream, syn::GenericArgument) {
|
||||
let mut result;
|
||||
let mut succ;
|
||||
|
||||
match ty {
|
||||
syn::Type::Path(ref typath) => {
|
||||
if let Some(segment) = typath.path.segments.last() {
|
||||
match segment.ident.to_string().as_str() {
|
||||
// check for PyResult<T>
|
||||
"PyResult" => match segment.arguments {
|
||||
syn::PathArguments::AngleBracketed(ref data) => {
|
||||
result = true;
|
||||
succ = data.args[0].clone();
|
||||
|
||||
// check for PyResult<Option<T>>
|
||||
if let syn::GenericArgument::Type(syn::Type::Path(ref typath)) =
|
||||
data.args[0]
|
||||
{
|
||||
if let Some(segment) = typath.path.segments.last() {
|
||||
if "Option" == segment.ident.to_string().as_str() {
|
||||
// get T from Option<T>
|
||||
if let syn::PathArguments::AngleBracketed(ref data) =
|
||||
segment.arguments
|
||||
{
|
||||
result = false;
|
||||
succ = data.args[0].clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => panic!("fn result type is not supported"),
|
||||
},
|
||||
_ => panic!(
|
||||
"fn result type has to be PyResult or (), got {:?}",
|
||||
segment.ident
|
||||
),
|
||||
}
|
||||
} else {
|
||||
panic!("fn result is not supported {:?}", typath)
|
||||
}
|
||||
}
|
||||
_ => panic!("not supported: {:?}", ty),
|
||||
};
|
||||
|
||||
// result
|
||||
let res = if result {
|
||||
quote! {PyResult<#succ>}
|
||||
} else {
|
||||
quote! {#ty}
|
||||
};
|
||||
|
||||
(res, succ)
|
||||
}
|
||||
|
||||
fn extract_decl(spec: syn::Item) -> syn::Signature {
|
||||
match spec {
|
||||
syn::Item::Fn(f) => f.sig,
|
||||
|
|
|
@ -79,19 +79,40 @@ impl IntoPyCallbackOutput<()> for () {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct LenCallbackOutput(pub usize);
|
||||
|
||||
impl IntoPyCallbackOutput<ffi::Py_ssize_t> for LenCallbackOutput {
|
||||
impl IntoPyCallbackOutput<ffi::Py_ssize_t> for usize {
|
||||
#[inline]
|
||||
fn convert(self, _py: Python) -> PyResult<ffi::Py_ssize_t> {
|
||||
if self.0 <= (isize::MAX as usize) {
|
||||
Ok(self.0 as isize)
|
||||
if self <= (isize::MAX as usize) {
|
||||
Ok(self as isize)
|
||||
} else {
|
||||
Err(OverflowError::py_err(()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Converters needed for `#[pyproto]` implementations
|
||||
|
||||
impl IntoPyCallbackOutput<bool> for bool {
|
||||
fn convert(self, _: Python) -> PyResult<bool> {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoPyCallbackOutput<usize> for usize {
|
||||
fn convert(self, _: Python) -> PyResult<usize> {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> IntoPyCallbackOutput<PyObject> for T
|
||||
where
|
||||
T: IntoPy<PyObject>,
|
||||
{
|
||||
fn convert(self, py: Python) -> PyResult<PyObject> {
|
||||
Ok(self.into_py(py))
|
||||
}
|
||||
}
|
||||
|
||||
pub trait WrappingCastTo<T> {
|
||||
fn wrapping_cast(self) -> T;
|
||||
}
|
||||
|
@ -117,15 +138,12 @@ wrapping_cast!(i32, Py_hash_t);
|
|||
wrapping_cast!(isize, Py_hash_t);
|
||||
wrapping_cast!(i64, Py_hash_t);
|
||||
|
||||
pub struct HashCallbackOutput<T>(pub T);
|
||||
pub struct HashCallbackOutput(Py_hash_t);
|
||||
|
||||
impl<T> IntoPyCallbackOutput<Py_hash_t> for HashCallbackOutput<T>
|
||||
where
|
||||
T: WrappingCastTo<Py_hash_t>,
|
||||
{
|
||||
impl IntoPyCallbackOutput<Py_hash_t> for HashCallbackOutput {
|
||||
#[inline]
|
||||
fn convert(self, _py: Python) -> PyResult<Py_hash_t> {
|
||||
let hash = self.0.wrapping_cast();
|
||||
let hash = self.0;
|
||||
if hash == -1 {
|
||||
Ok(-2)
|
||||
} else {
|
||||
|
@ -134,6 +152,16 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> IntoPyCallbackOutput<HashCallbackOutput> for T
|
||||
where
|
||||
T: WrappingCastTo<Py_hash_t>,
|
||||
{
|
||||
#[inline]
|
||||
fn convert(self, _py: Python) -> PyResult<HashCallbackOutput> {
|
||||
Ok(HashCallbackOutput(self.wrapping_cast()))
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[inline]
|
||||
pub fn convert<T, U>(py: Python, value: T) -> PyResult<U>
|
||||
|
|
|
@ -8,10 +8,8 @@
|
|||
//! Parts of the documentation are copied from the respective methods from the
|
||||
//! [typeobj docs](https://docs.python.org/3/c-api/typeobj.html)
|
||||
|
||||
use crate::callback::HashCallbackOutput;
|
||||
use crate::{
|
||||
exceptions, ffi, FromPyObject, IntoPy, PyAny, PyCell, PyClass, PyErr, PyObject, PyResult,
|
||||
};
|
||||
use crate::callback::{HashCallbackOutput, IntoPyCallbackOutput};
|
||||
use crate::{exceptions, ffi, FromPyObject, PyAny, PyCell, PyClass, PyErr, PyObject, PyResult};
|
||||
use std::os::raw::c_int;
|
||||
|
||||
/// Operators for the __richcmp__ method
|
||||
|
@ -100,45 +98,39 @@ pub trait PyObjectProtocol<'p>: PyClass {
|
|||
|
||||
pub trait PyObjectGetAttrProtocol<'p>: PyObjectProtocol<'p> {
|
||||
type Name: FromPyObject<'p>;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
pub trait PyObjectSetAttrProtocol<'p>: PyObjectProtocol<'p> {
|
||||
type Name: FromPyObject<'p>;
|
||||
type Value: FromPyObject<'p>;
|
||||
type Result: Into<PyResult<()>>;
|
||||
type Result: IntoPyCallbackOutput<()>;
|
||||
}
|
||||
pub trait PyObjectDelAttrProtocol<'p>: PyObjectProtocol<'p> {
|
||||
type Name: FromPyObject<'p>;
|
||||
type Result: Into<PyResult<()>>;
|
||||
type Result: IntoPyCallbackOutput<()>;
|
||||
}
|
||||
pub trait PyObjectStrProtocol<'p>: PyObjectProtocol<'p> {
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
pub trait PyObjectReprProtocol<'p>: PyObjectProtocol<'p> {
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
pub trait PyObjectFormatProtocol<'p>: PyObjectProtocol<'p> {
|
||||
type Format: FromPyObject<'p>;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
pub trait PyObjectHashProtocol<'p>: PyObjectProtocol<'p> {
|
||||
type Result: Into<PyResult<isize>>;
|
||||
type Result: IntoPyCallbackOutput<HashCallbackOutput>;
|
||||
}
|
||||
pub trait PyObjectBoolProtocol<'p>: PyObjectProtocol<'p> {
|
||||
type Result: Into<PyResult<bool>>;
|
||||
type Result: IntoPyCallbackOutput<bool>;
|
||||
}
|
||||
pub trait PyObjectBytesProtocol<'p>: PyObjectProtocol<'p> {
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
pub trait PyObjectRichcmpProtocol<'p>: PyObjectProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
/// All FFI functions for basic protocols.
|
||||
|
@ -180,12 +172,7 @@ impl PyObjectMethods {
|
|||
where
|
||||
T: for<'p> PyObjectHashProtocol<'p>,
|
||||
{
|
||||
self.tp_hash = py_unary_func!(
|
||||
PyObjectHashProtocol,
|
||||
T::__hash__,
|
||||
ffi::Py_hash_t,
|
||||
HashCallbackOutput
|
||||
);
|
||||
self.tp_hash = py_unary_func!(PyObjectHashProtocol, T::__hash__, ffi::Py_hash_t);
|
||||
}
|
||||
pub fn set_getattr<T>(&mut self)
|
||||
where
|
||||
|
@ -255,7 +242,7 @@ where
|
|||
|
||||
let slf = py.from_borrowed_ptr::<PyCell<T>>(slf);
|
||||
let arg = py.from_borrowed_ptr::<PyAny>(arg);
|
||||
call_ref!(slf, __getattr__, arg)
|
||||
call_ref!(slf, __getattr__, arg).convert(py)
|
||||
})
|
||||
}
|
||||
Some(wrap::<T>)
|
||||
|
@ -293,7 +280,7 @@ where
|
|||
let op = extract_op(op)?;
|
||||
let arg = arg.extract()?;
|
||||
|
||||
slf.try_borrow()?.__richcmp__(arg, op).into()
|
||||
slf.try_borrow()?.__richcmp__(arg, op).convert(py)
|
||||
})
|
||||
}
|
||||
Some(wrap::<T>)
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
//!
|
||||
//! For more information check [buffer protocol](https://docs.python.org/3/c-api/buffer.html)
|
||||
//! c-api
|
||||
use crate::err::PyResult;
|
||||
use crate::callback::IntoPyCallbackOutput;
|
||||
use crate::{
|
||||
ffi::{self, PyBufferProcs},
|
||||
PyCell, PyClass, PyRefMut,
|
||||
|
@ -33,11 +33,11 @@ pub trait PyBufferProtocol<'p>: PyClass {
|
|||
}
|
||||
|
||||
pub trait PyBufferGetBufferProtocol<'p>: PyBufferProtocol<'p> {
|
||||
type Result: Into<PyResult<()>>;
|
||||
type Result: IntoPyCallbackOutput<()>;
|
||||
}
|
||||
|
||||
pub trait PyBufferReleaseBufferProtocol<'p>: PyBufferProtocol<'p> {
|
||||
type Result: Into<PyResult<()>>;
|
||||
type Result: IntoPyCallbackOutput<()>;
|
||||
}
|
||||
|
||||
/// Set functions used by `#[pyproto]`.
|
||||
|
@ -71,7 +71,7 @@ where
|
|||
{
|
||||
crate::callback_body!(py, {
|
||||
let slf = py.from_borrowed_ptr::<PyCell<T>>(slf);
|
||||
T::bf_getbuffer(slf.try_borrow_mut()?, arg1, arg2).into()
|
||||
T::bf_getbuffer(slf.try_borrow_mut()?, arg1, arg2).convert(py)
|
||||
})
|
||||
}
|
||||
Some(wrap::<T>)
|
||||
|
@ -87,7 +87,7 @@ where
|
|||
{
|
||||
crate::callback_body!(py, {
|
||||
let slf = py.from_borrowed_ptr::<crate::PyCell<T>>(slf);
|
||||
T::bf_releasebuffer(slf.try_borrow_mut()?, arg1).into()
|
||||
T::bf_releasebuffer(slf.try_borrow_mut()?, arg1).convert(py)
|
||||
})
|
||||
}
|
||||
Some(wrap::<T>)
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
//! Trait and support implementation for context manager api
|
||||
//!
|
||||
|
||||
use crate::err::PyResult;
|
||||
use crate::callback::IntoPyCallbackOutput;
|
||||
use crate::{PyClass, PyObject};
|
||||
|
||||
/// Context manager interface
|
||||
|
@ -31,14 +31,12 @@ pub trait PyContextProtocol<'p>: PyClass {
|
|||
}
|
||||
|
||||
pub trait PyContextEnterProtocol<'p>: PyContextProtocol<'p> {
|
||||
type Success: crate::IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyContextExitProtocol<'p>: PyContextProtocol<'p> {
|
||||
type ExcType: crate::FromPyObject<'p>;
|
||||
type ExcValue: crate::FromPyObject<'p>;
|
||||
type Traceback: crate::FromPyObject<'p>;
|
||||
type Success: crate::IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
//! [Python information](
|
||||
//! https://docs.python.org/3/reference/datamodel.html#implementing-descriptors)
|
||||
|
||||
use crate::err::PyResult;
|
||||
use crate::callback::IntoPyCallbackOutput;
|
||||
use crate::types::PyAny;
|
||||
use crate::{ffi, FromPyObject, IntoPy, PyClass, PyObject};
|
||||
use crate::{ffi, FromPyObject, PyClass, PyObject};
|
||||
use std::os::raw::c_int;
|
||||
|
||||
/// Descriptor interface
|
||||
|
@ -50,25 +50,24 @@ pub trait PyDescrGetProtocol<'p>: PyDescrProtocol<'p> {
|
|||
type Receiver: crate::derive_utils::TryFromPyCell<'p, Self>;
|
||||
type Inst: FromPyObject<'p>;
|
||||
type Owner: FromPyObject<'p>;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyDescrSetProtocol<'p>: PyDescrProtocol<'p> {
|
||||
type Receiver: crate::derive_utils::TryFromPyCell<'p, Self>;
|
||||
type Inst: FromPyObject<'p>;
|
||||
type Value: FromPyObject<'p>;
|
||||
type Result: Into<PyResult<()>>;
|
||||
type Result: IntoPyCallbackOutput<()>;
|
||||
}
|
||||
|
||||
pub trait PyDescrDeleteProtocol<'p>: PyDescrProtocol<'p> {
|
||||
type Inst: FromPyObject<'p>;
|
||||
type Result: Into<PyResult<()>>;
|
||||
type Result: IntoPyCallbackOutput<()>;
|
||||
}
|
||||
|
||||
pub trait PyDescrSetNameProtocol<'p>: PyDescrProtocol<'p> {
|
||||
type Inst: FromPyObject<'p>;
|
||||
type Result: Into<PyResult<()>>;
|
||||
type Result: IntoPyCallbackOutput<()>;
|
||||
}
|
||||
|
||||
/// All FFI functions for description protocols.
|
||||
|
|
|
@ -30,14 +30,12 @@ pub trait PyIterProtocol<'p>: PyClass {
|
|||
|
||||
pub trait PyIterIterProtocol<'p>: PyIterProtocol<'p> {
|
||||
type Receiver: TryFromPyCell<'p, Self>;
|
||||
type Success: crate::IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyIterNextProtocol<'p>: PyIterProtocol<'p> {
|
||||
type Receiver: TryFromPyCell<'p, Self>;
|
||||
type Success: crate::IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Option<Self::Success>>>;
|
||||
type Result: IntoPyCallbackOutput<IterNextOutput>;
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -62,20 +60,26 @@ impl PyIterMethods {
|
|||
where
|
||||
T: for<'p> PyIterNextProtocol<'p>,
|
||||
{
|
||||
self.tp_iternext = py_unarys_func!(PyIterNextProtocol, T::__next__, IterNextConverter);
|
||||
self.tp_iternext = py_unarys_func!(PyIterNextProtocol, T::__next__);
|
||||
}
|
||||
}
|
||||
|
||||
struct IterNextConverter<T>(Option<T>);
|
||||
pub struct IterNextOutput(Option<PyObject>);
|
||||
|
||||
impl<T> IntoPyCallbackOutput<*mut ffi::PyObject> for IterNextConverter<T>
|
||||
where
|
||||
T: IntoPy<PyObject>,
|
||||
{
|
||||
fn convert(self, py: Python) -> PyResult<*mut ffi::PyObject> {
|
||||
impl IntoPyCallbackOutput<*mut ffi::PyObject> for IterNextOutput {
|
||||
fn convert(self, _py: Python) -> PyResult<*mut ffi::PyObject> {
|
||||
match self.0 {
|
||||
Some(val) => Ok(val.into_py(py).into_ptr()),
|
||||
Some(o) => Ok(o.into_ptr()),
|
||||
None => Err(crate::exceptions::StopIteration::py_err(())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> IntoPyCallbackOutput<IterNextOutput> for Option<T>
|
||||
where
|
||||
T: IntoPy<PyObject>,
|
||||
{
|
||||
fn convert(self, py: Python) -> PyResult<IterNextOutput> {
|
||||
Ok(IterNextOutput(self.map(|o| o.into_py(py))))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,31 +3,31 @@
|
|||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! py_unary_func {
|
||||
($trait: ident, $class:ident :: $f:ident, $call:ident, $ret_type: ty $(, $conv:expr)?) => {{
|
||||
($trait: ident, $class:ident :: $f:ident, $call:ident, $ret_type: ty) => {{
|
||||
unsafe extern "C" fn wrap<T>(slf: *mut $crate::ffi::PyObject) -> $ret_type
|
||||
where
|
||||
T: for<'p> $trait<'p>,
|
||||
{
|
||||
$crate::callback_body!(py, {
|
||||
let slf = py.from_borrowed_ptr::<$crate::PyCell<T>>(slf);
|
||||
$call!(slf, $f)$(.map($conv))?
|
||||
$call!(slf, $f).convert(py)
|
||||
})
|
||||
}
|
||||
Some(wrap::<$class>)
|
||||
}};
|
||||
// Use call_ref! by default
|
||||
($trait:ident, $class:ident :: $f:ident, $ret_type:ty $(, $conv:expr)?) => {
|
||||
py_unary_func!($trait, $class::$f, call_ref, $ret_type $(, $conv)?);
|
||||
($trait:ident, $class:ident :: $f:ident, $ret_type:ty) => {
|
||||
py_unary_func!($trait, $class::$f, call_ref, $ret_type);
|
||||
};
|
||||
($trait:ident, $class:ident :: $f:ident $(, $conv:expr)?) => {
|
||||
py_unary_func!($trait, $class::$f, call_ref, *mut $crate::ffi::PyObject $(, $conv)?);
|
||||
($trait:ident, $class:ident :: $f:ident) => {
|
||||
py_unary_func!($trait, $class::$f, call_ref, *mut $crate::ffi::PyObject);
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! py_unarys_func {
|
||||
($trait:ident, $class:ident :: $f:ident $(, $conv:expr)?) => {{
|
||||
($trait:ident, $class:ident :: $f:ident) => {{
|
||||
unsafe extern "C" fn wrap<T>(slf: *mut $crate::ffi::PyObject) -> *mut $crate::ffi::PyObject
|
||||
where
|
||||
T: for<'p> $trait<'p>,
|
||||
|
@ -38,7 +38,7 @@ macro_rules! py_unarys_func {
|
|||
<T::Receiver as $crate::derive_utils::TryFromPyCell<_>>::try_from_pycell(slf)
|
||||
.map_err(|e| e.into())?;
|
||||
|
||||
$class::$f(borrow).into()$(.map($conv))?
|
||||
$class::$f(borrow).convert(py)
|
||||
})
|
||||
}
|
||||
Some(wrap::<$class>)
|
||||
|
@ -49,12 +49,7 @@ macro_rules! py_unarys_func {
|
|||
#[doc(hidden)]
|
||||
macro_rules! py_len_func {
|
||||
($trait:ident, $class:ident :: $f:ident) => {
|
||||
py_unary_func!(
|
||||
$trait,
|
||||
$class::$f,
|
||||
$crate::ffi::Py_ssize_t,
|
||||
$crate::callback::LenCallbackOutput
|
||||
)
|
||||
py_unary_func!($trait, $class::$f, $crate::ffi::Py_ssize_t)
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -62,7 +57,7 @@ macro_rules! py_len_func {
|
|||
#[doc(hidden)]
|
||||
macro_rules! py_binary_func {
|
||||
// Use call_ref! by default
|
||||
($trait:ident, $class:ident :: $f:ident, $return:ty, $call:ident $(, $conv:expr)?) => {{
|
||||
($trait:ident, $class:ident :: $f:ident, $return:ty, $call:ident) => {{
|
||||
unsafe extern "C" fn wrap<T>(slf: *mut ffi::PyObject, arg: *mut ffi::PyObject) -> $return
|
||||
where
|
||||
T: for<'p> $trait<'p>,
|
||||
|
@ -70,16 +65,16 @@ macro_rules! py_binary_func {
|
|||
$crate::callback_body!(py, {
|
||||
let slf = py.from_borrowed_ptr::<$crate::PyCell<T>>(slf);
|
||||
let arg = py.from_borrowed_ptr::<$crate::PyAny>(arg);
|
||||
$call!(slf, $f, arg)$(.map($conv))?
|
||||
$call!(slf, $f, arg).convert(py)
|
||||
})
|
||||
}
|
||||
Some(wrap::<$class>)
|
||||
}};
|
||||
($trait:ident, $class:ident :: $f:ident, $return:ty $(, $conv:expr)?) => {
|
||||
py_binary_func!($trait, $class::$f, $return, call_ref $(, $conv)?)
|
||||
($trait:ident, $class:ident :: $f:ident, $return:ty) => {
|
||||
py_binary_func!($trait, $class::$f, $return, call_ref)
|
||||
};
|
||||
($trait:ident, $class:ident :: $f:ident $(, $conv:expr)?) => {
|
||||
py_binary_func!($trait, $class::$f, *mut $crate::ffi::PyObject $(, $conv)?)
|
||||
($trait:ident, $class:ident :: $f:ident) => {
|
||||
py_binary_func!($trait, $class::$f, *mut $crate::ffi::PyObject)
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -98,7 +93,7 @@ macro_rules! py_binary_num_func {
|
|||
let lhs = py.from_borrowed_ptr::<$crate::PyAny>(lhs);
|
||||
let rhs = py.from_borrowed_ptr::<$crate::PyAny>(rhs);
|
||||
|
||||
$class::$f(lhs.extract()?, rhs.extract()?).into()
|
||||
$class::$f(lhs.extract()?, rhs.extract()?).convert(py)
|
||||
})
|
||||
}
|
||||
Some(wrap::<$class>)
|
||||
|
@ -121,7 +116,7 @@ macro_rules! py_binary_reversed_num_func {
|
|||
let slf = py.from_borrowed_ptr::<$crate::PyCell<T>>(rhs);
|
||||
let arg = py.from_borrowed_ptr::<$crate::PyAny>(lhs);
|
||||
|
||||
$class::$f(&*slf.try_borrow()?, arg.extract()?).into()
|
||||
$class::$f(&*slf.try_borrow()?, arg.extract()?).convert(py)
|
||||
})
|
||||
}
|
||||
Some(wrap::<$class>)
|
||||
|
@ -143,7 +138,7 @@ macro_rules! py_binary_self_func {
|
|||
$crate::callback_body!(py, {
|
||||
let slf_ = py.from_borrowed_ptr::<$crate::PyCell<T>>(slf);
|
||||
let arg = py.from_borrowed_ptr::<$crate::PyAny>(arg);
|
||||
call_mut!(slf_, $f, arg)?;
|
||||
call_mut!(slf_, $f, arg).convert(py)?;
|
||||
ffi::Py_INCREF(slf);
|
||||
Ok(slf)
|
||||
})
|
||||
|
@ -169,7 +164,7 @@ macro_rules! py_ssizearg_func {
|
|||
{
|
||||
$crate::callback_body!(py, {
|
||||
let slf = py.from_borrowed_ptr::<$crate::PyCell<T>>(slf);
|
||||
$call!(slf, $f; arg.into())
|
||||
$call!(slf, $f; arg.into()).convert(py)
|
||||
})
|
||||
}
|
||||
Some(wrap::<$class>)
|
||||
|
@ -200,7 +195,7 @@ macro_rules! py_ternarys_func {
|
|||
.from_borrowed_ptr::<$crate::types::PyAny>(arg2)
|
||||
.extract()?;
|
||||
|
||||
$class::$f(slf, arg1, arg2).into()
|
||||
$class::$f(slf, arg1, arg2).convert(py)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -234,7 +229,7 @@ macro_rules! py_ternary_num_func {
|
|||
.from_borrowed_ptr::<$crate::types::PyAny>(arg3)
|
||||
.extract()?;
|
||||
|
||||
$class::$f(arg1, arg2, arg3).into()
|
||||
$class::$f(arg1, arg2, arg3).convert(py)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -260,7 +255,7 @@ macro_rules! py_ternary_reversed_num_func {
|
|||
let arg1 = py.from_borrowed_ptr::<$crate::PyAny>(arg1);
|
||||
let arg2 = py.from_borrowed_ptr::<$crate::PyAny>(arg3);
|
||||
|
||||
$class::$f(&*slf.try_borrow()?, arg1.extract()?, arg2.extract()?).into()
|
||||
$class::$f(&*slf.try_borrow()?, arg1.extract()?, arg2.extract()?).convert(py)
|
||||
})
|
||||
}
|
||||
Some(wrap::<$class>)
|
||||
|
@ -284,7 +279,7 @@ macro_rules! py_dummy_ternary_self_func {
|
|||
$crate::callback_body!(py, {
|
||||
let slf_cell = py.from_borrowed_ptr::<$crate::PyCell<T>>(slf);
|
||||
let arg1 = py.from_borrowed_ptr::<$crate::PyAny>(arg1);
|
||||
call_mut!(slf_cell, $f, arg1)?;
|
||||
call_mut!(slf_cell, $f, arg1).convert(py)?;
|
||||
ffi::Py_INCREF(slf);
|
||||
Ok(slf)
|
||||
})
|
||||
|
@ -316,7 +311,7 @@ macro_rules! py_func_set {
|
|||
} else {
|
||||
let name = py.from_borrowed_ptr::<$crate::PyAny>(name);
|
||||
let value = py.from_borrowed_ptr::<$crate::PyAny>(value);
|
||||
call_mut!(slf, $fn_set, name, value)
|
||||
call_mut!(slf, $fn_set, name, value).convert(py)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -341,7 +336,7 @@ macro_rules! py_func_del {
|
|||
let name = py
|
||||
.from_borrowed_ptr::<$crate::types::PyAny>(name)
|
||||
.extract()?;
|
||||
slf.try_borrow_mut()?.$fn_del(name).into()
|
||||
slf.try_borrow_mut()?.$fn_del(name).convert(py)
|
||||
} else {
|
||||
Err(PyErr::new::<exceptions::NotImplementedError, _>(
|
||||
"Subscript assignment not supported",
|
||||
|
@ -369,10 +364,10 @@ macro_rules! py_func_set_del {
|
|||
let name = py.from_borrowed_ptr::<$crate::PyAny>(name);
|
||||
|
||||
if value.is_null() {
|
||||
call_mut!(slf, $fn_del, name)
|
||||
call_mut!(slf, $fn_del, name).convert(py)
|
||||
} else {
|
||||
let value = py.from_borrowed_ptr::<$crate::PyAny>(value);
|
||||
call_mut!(slf, $fn_set, name, value)
|
||||
call_mut!(slf, $fn_set, name, value).convert(py)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -382,7 +377,7 @@ macro_rules! py_func_set_del {
|
|||
|
||||
macro_rules! _call_impl {
|
||||
($slf: expr, $fn: ident $(; $args: expr)*) => {
|
||||
$slf.$fn($($args,)*).into()
|
||||
$slf.$fn($($args,)*)
|
||||
};
|
||||
($slf: expr, $fn: ident, $raw_arg: expr $(,$raw_args: expr)* $(; $args: expr)*) => {
|
||||
_call_impl!($slf, $fn $(,$raw_args)* $(;$args)* ;$raw_arg.extract()?)
|
||||
|
|
|
@ -3,8 +3,9 @@
|
|||
//! Python Mapping Interface
|
||||
//! Trait and support implementation for implementing mapping support
|
||||
|
||||
use crate::err::{PyErr, PyResult};
|
||||
use crate::{exceptions, ffi, FromPyObject, IntoPy, PyClass, PyObject};
|
||||
use crate::callback::IntoPyCallbackOutput;
|
||||
use crate::err::PyErr;
|
||||
use crate::{exceptions, ffi, FromPyObject, PyClass, PyObject};
|
||||
|
||||
/// Mapping interface
|
||||
#[allow(unused_variables)]
|
||||
|
@ -49,29 +50,27 @@ pub trait PyMappingProtocol<'p>: PyClass {
|
|||
// the existance of a slotted method.
|
||||
|
||||
pub trait PyMappingLenProtocol<'p>: PyMappingProtocol<'p> {
|
||||
type Result: Into<PyResult<usize>>;
|
||||
type Result: IntoPyCallbackOutput<usize>;
|
||||
}
|
||||
|
||||
pub trait PyMappingGetItemProtocol<'p>: PyMappingProtocol<'p> {
|
||||
type Key: FromPyObject<'p>;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyMappingSetItemProtocol<'p>: PyMappingProtocol<'p> {
|
||||
type Key: FromPyObject<'p>;
|
||||
type Value: FromPyObject<'p>;
|
||||
type Result: Into<PyResult<()>>;
|
||||
type Result: IntoPyCallbackOutput<()>;
|
||||
}
|
||||
|
||||
pub trait PyMappingDelItemProtocol<'p>: PyMappingProtocol<'p> {
|
||||
type Key: FromPyObject<'p>;
|
||||
type Result: Into<PyResult<()>>;
|
||||
type Result: IntoPyCallbackOutput<()>;
|
||||
}
|
||||
|
||||
pub trait PyMappingReversedProtocol<'p>: PyMappingProtocol<'p> {
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
//! Python Number Interface
|
||||
//! Trait and support implementation for implementing number protocol
|
||||
|
||||
use crate::err::PyResult;
|
||||
use crate::{ffi, FromPyObject, IntoPy, PyClass, PyObject};
|
||||
use crate::callback::IntoPyCallbackOutput;
|
||||
use crate::{ffi, FromPyObject, PyClass, PyObject};
|
||||
|
||||
/// Number interface
|
||||
#[allow(unused_variables)]
|
||||
|
@ -318,301 +318,264 @@ pub trait PyNumberProtocol<'p>: PyClass {
|
|||
pub trait PyNumberAddProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Left: FromPyObject<'p>;
|
||||
type Right: FromPyObject<'p>;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyNumberSubProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Left: FromPyObject<'p>;
|
||||
type Right: FromPyObject<'p>;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyNumberMulProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Left: FromPyObject<'p>;
|
||||
type Right: FromPyObject<'p>;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyNumberMatmulProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Left: FromPyObject<'p>;
|
||||
type Right: FromPyObject<'p>;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyNumberTruedivProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Left: FromPyObject<'p>;
|
||||
type Right: FromPyObject<'p>;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyNumberFloordivProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Left: FromPyObject<'p>;
|
||||
type Right: FromPyObject<'p>;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyNumberModProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Left: FromPyObject<'p>;
|
||||
type Right: FromPyObject<'p>;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyNumberDivmodProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Left: FromPyObject<'p>;
|
||||
type Right: FromPyObject<'p>;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyNumberPowProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Left: FromPyObject<'p>;
|
||||
type Right: FromPyObject<'p>;
|
||||
type Modulo: FromPyObject<'p>;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyNumberLShiftProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Left: FromPyObject<'p>;
|
||||
type Right: FromPyObject<'p>;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyNumberRShiftProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Left: FromPyObject<'p>;
|
||||
type Right: FromPyObject<'p>;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyNumberAndProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Left: FromPyObject<'p>;
|
||||
type Right: FromPyObject<'p>;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyNumberXorProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Left: FromPyObject<'p>;
|
||||
type Right: FromPyObject<'p>;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyNumberOrProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Left: FromPyObject<'p>;
|
||||
type Right: FromPyObject<'p>;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyNumberRAddProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyNumberRSubProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyNumberRMulProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyNumberRMatmulProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyNumberRTruedivProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyNumberRFloordivProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyNumberRModProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyNumberRDivmodProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyNumberRPowProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Modulo: FromPyObject<'p>;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyNumberRLShiftProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyNumberRRShiftProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyNumberRAndProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyNumberRXorProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyNumberROrProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyNumberIAddProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Result: Into<PyResult<()>>;
|
||||
type Result: IntoPyCallbackOutput<()>;
|
||||
}
|
||||
|
||||
pub trait PyNumberISubProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Result: Into<PyResult<()>>;
|
||||
type Result: IntoPyCallbackOutput<()>;
|
||||
}
|
||||
|
||||
pub trait PyNumberIMulProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Result: Into<PyResult<()>>;
|
||||
type Result: IntoPyCallbackOutput<()>;
|
||||
}
|
||||
|
||||
pub trait PyNumberIMatmulProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Result: Into<PyResult<()>>;
|
||||
type Result: IntoPyCallbackOutput<()>;
|
||||
}
|
||||
|
||||
pub trait PyNumberITruedivProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Result: Into<PyResult<()>>;
|
||||
type Result: IntoPyCallbackOutput<()>;
|
||||
}
|
||||
|
||||
pub trait PyNumberIFloordivProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Result: Into<PyResult<()>>;
|
||||
type Result: IntoPyCallbackOutput<()>;
|
||||
}
|
||||
|
||||
pub trait PyNumberIModProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Result: Into<PyResult<()>>;
|
||||
type Result: IntoPyCallbackOutput<()>;
|
||||
}
|
||||
|
||||
pub trait PyNumberIDivmodProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Result: Into<PyResult<()>>;
|
||||
type Result: IntoPyCallbackOutput<()>;
|
||||
}
|
||||
|
||||
pub trait PyNumberIPowProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Result: Into<PyResult<()>>;
|
||||
type Result: IntoPyCallbackOutput<()>;
|
||||
}
|
||||
|
||||
pub trait PyNumberILShiftProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Result: Into<PyResult<()>>;
|
||||
type Result: IntoPyCallbackOutput<()>;
|
||||
}
|
||||
|
||||
pub trait PyNumberIRShiftProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Result: Into<PyResult<()>>;
|
||||
type Result: IntoPyCallbackOutput<()>;
|
||||
}
|
||||
|
||||
pub trait PyNumberIAndProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Result: Into<PyResult<()>>;
|
||||
type Result: IntoPyCallbackOutput<()>;
|
||||
}
|
||||
|
||||
pub trait PyNumberIXorProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Result: Into<PyResult<()>>;
|
||||
type Result: IntoPyCallbackOutput<()>;
|
||||
}
|
||||
|
||||
pub trait PyNumberIOrProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Result: Into<PyResult<()>>;
|
||||
type Result: IntoPyCallbackOutput<()>;
|
||||
}
|
||||
|
||||
pub trait PyNumberNegProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyNumberPosProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyNumberAbsProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyNumberInvertProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyNumberComplexProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyNumberIntProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyNumberFloatProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyNumberRoundProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Success: IntoPy<PyObject>;
|
||||
type NDigits: FromPyObject<'p>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyNumberIndexProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
|
|
|
@ -8,9 +8,10 @@
|
|||
//! [PEP-0492](https://www.python.org/dev/peps/pep-0492/)
|
||||
//!
|
||||
|
||||
use crate::callback::IntoPyCallbackOutput;
|
||||
use crate::derive_utils::TryFromPyCell;
|
||||
use crate::err::PyResult;
|
||||
use crate::{ffi, PyClass, PyObject};
|
||||
use crate::{ffi, IntoPy, IntoPyPointer, PyClass, PyObject, Python};
|
||||
|
||||
/// Python Async/Await support interface.
|
||||
///
|
||||
|
@ -60,33 +61,28 @@ pub trait PyAsyncProtocol<'p>: PyClass {
|
|||
|
||||
pub trait PyAsyncAwaitProtocol<'p>: PyAsyncProtocol<'p> {
|
||||
type Receiver: TryFromPyCell<'p, Self>;
|
||||
type Success: crate::IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyAsyncAiterProtocol<'p>: PyAsyncProtocol<'p> {
|
||||
type Receiver: TryFromPyCell<'p, Self>;
|
||||
type Success: crate::IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyAsyncAnextProtocol<'p>: PyAsyncProtocol<'p> {
|
||||
type Receiver: TryFromPyCell<'p, Self>;
|
||||
type Success: crate::IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Option<Self::Success>>>;
|
||||
type Result: IntoPyCallbackOutput<IterANextOutput>;
|
||||
}
|
||||
|
||||
pub trait PyAsyncAenterProtocol<'p>: PyAsyncProtocol<'p> {
|
||||
type Success: crate::IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PyAsyncAexitProtocol<'p>: PyAsyncProtocol<'p> {
|
||||
type ExcType: crate::FromPyObject<'p>;
|
||||
type ExcValue: crate::FromPyObject<'p>;
|
||||
type Traceback: crate::FromPyObject<'p>;
|
||||
type Success: crate::IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
|
@ -107,37 +103,34 @@ impl ffi::PyAsyncMethods {
|
|||
where
|
||||
T: for<'p> PyAsyncAnextProtocol<'p>,
|
||||
{
|
||||
self.am_anext = anext::am_anext::<T>();
|
||||
self.am_anext = am_anext::<T>();
|
||||
}
|
||||
}
|
||||
|
||||
mod anext {
|
||||
use super::PyAsyncAnextProtocol;
|
||||
use crate::callback::IntoPyCallbackOutput;
|
||||
use crate::err::PyResult;
|
||||
use crate::IntoPyPointer;
|
||||
use crate::Python;
|
||||
use crate::{ffi, IntoPy, PyObject};
|
||||
pub struct IterANextOutput(Option<PyObject>);
|
||||
|
||||
struct IterANextOutput<T>(Option<T>);
|
||||
|
||||
impl<T> IntoPyCallbackOutput<*mut ffi::PyObject> for IterANextOutput<T>
|
||||
where
|
||||
T: IntoPy<PyObject>,
|
||||
{
|
||||
fn convert(self, py: Python) -> PyResult<*mut ffi::PyObject> {
|
||||
match self.0 {
|
||||
Some(val) => Ok(val.into_py(py).into_ptr()),
|
||||
None => Err(crate::exceptions::StopAsyncIteration::py_err(())),
|
||||
}
|
||||
impl IntoPyCallbackOutput<*mut ffi::PyObject> for IterANextOutput {
|
||||
fn convert(self, _py: Python) -> PyResult<*mut ffi::PyObject> {
|
||||
match self.0 {
|
||||
Some(o) => Ok(o.into_ptr()),
|
||||
None => Err(crate::exceptions::StopAsyncIteration::py_err(())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super) fn am_anext<T>() -> Option<ffi::unaryfunc>
|
||||
where
|
||||
T: for<'p> PyAsyncAnextProtocol<'p>,
|
||||
{
|
||||
py_unarys_func!(PyAsyncAnextProtocol, T::__anext__, IterANextOutput)
|
||||
impl<T> IntoPyCallbackOutput<IterANextOutput> for Option<T>
|
||||
where
|
||||
T: IntoPy<PyObject>,
|
||||
{
|
||||
fn convert(self, py: Python) -> PyResult<IterANextOutput> {
|
||||
Ok(IterANextOutput(self.map(|o| o.into_py(py))))
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn am_anext<T>() -> Option<ffi::unaryfunc>
|
||||
where
|
||||
T: for<'p> PyAsyncAnextProtocol<'p>,
|
||||
{
|
||||
py_unarys_func!(PyAsyncAnextProtocol, T::__anext__)
|
||||
}
|
||||
|
|
|
@ -3,8 +3,9 @@
|
|||
//! Python Sequence Interface
|
||||
//! Trait and support implementation for implementing sequence
|
||||
|
||||
use crate::callback::IntoPyCallbackOutput;
|
||||
use crate::conversion::{FromPyObject, IntoPy};
|
||||
use crate::err::{PyErr, PyResult};
|
||||
use crate::err::PyErr;
|
||||
use crate::{exceptions, ffi, PyAny, PyCell, PyClass, PyObject};
|
||||
use std::os::raw::c_int;
|
||||
|
||||
|
@ -79,51 +80,52 @@ pub trait PySequenceProtocol<'p>: PyClass + Sized {
|
|||
// the existance of a slotted method.
|
||||
|
||||
pub trait PySequenceLenProtocol<'p>: PySequenceProtocol<'p> {
|
||||
type Result: Into<PyResult<usize>>;
|
||||
type Result: IntoPyCallbackOutput<usize>;
|
||||
}
|
||||
|
||||
pub trait PySequenceGetItemProtocol<'p>: PySequenceProtocol<'p> {
|
||||
type Index: FromPyObject<'p> + From<isize>;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PySequenceSetItemProtocol<'p>: PySequenceProtocol<'p> {
|
||||
type Index: FromPyObject<'p> + From<isize>;
|
||||
type Value: FromPyObject<'p>;
|
||||
type Result: Into<PyResult<()>>;
|
||||
type Result: IntoPyCallbackOutput<()>;
|
||||
}
|
||||
|
||||
pub trait PySequenceDelItemProtocol<'p>: PySequenceProtocol<'p> {
|
||||
type Index: FromPyObject<'p> + From<isize>;
|
||||
type Result: Into<PyResult<()>>;
|
||||
type Result: IntoPyCallbackOutput<()>;
|
||||
}
|
||||
|
||||
pub trait PySequenceContainsProtocol<'p>: PySequenceProtocol<'p> {
|
||||
type Item: FromPyObject<'p>;
|
||||
type Result: Into<PyResult<bool>>;
|
||||
type Result: IntoPyCallbackOutput<bool>;
|
||||
}
|
||||
|
||||
pub trait PySequenceConcatProtocol<'p>: PySequenceProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PySequenceRepeatProtocol<'p>: PySequenceProtocol<'p> {
|
||||
type Index: FromPyObject<'p> + From<isize>;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
type Result: IntoPyCallbackOutput<PyObject>;
|
||||
}
|
||||
|
||||
pub trait PySequenceInplaceConcatProtocol<'p>: PySequenceProtocol<'p> + IntoPy<PyObject> {
|
||||
pub trait PySequenceInplaceConcatProtocol<'p>:
|
||||
PySequenceProtocol<'p> + IntoPy<PyObject> + 'p
|
||||
{
|
||||
type Other: FromPyObject<'p>;
|
||||
type Result: Into<PyResult<Self>>;
|
||||
type Result: IntoPyCallbackOutput<Self>;
|
||||
}
|
||||
|
||||
pub trait PySequenceInplaceRepeatProtocol<'p>: PySequenceProtocol<'p> + IntoPy<PyObject> {
|
||||
pub trait PySequenceInplaceRepeatProtocol<'p>:
|
||||
PySequenceProtocol<'p> + IntoPy<PyObject> + 'p
|
||||
{
|
||||
type Index: FromPyObject<'p> + From<isize>;
|
||||
type Result: Into<PyResult<Self>>;
|
||||
type Result: IntoPyCallbackOutput<Self>;
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
|
@ -230,7 +232,7 @@ mod sq_ass_item_impl {
|
|||
let mut slf = slf.try_borrow_mut()?;
|
||||
let value = py.from_borrowed_ptr::<PyAny>(value);
|
||||
let value = value.extract()?;
|
||||
slf.__setitem__(key.into(), value).into()
|
||||
crate::callback::convert(py, slf.__setitem__(key.into(), value))
|
||||
})
|
||||
}
|
||||
Some(wrap::<T>)
|
||||
|
@ -252,7 +254,7 @@ mod sq_ass_item_impl {
|
|||
let slf = py.from_borrowed_ptr::<PyCell<T>>(slf);
|
||||
|
||||
if value.is_null() {
|
||||
slf.borrow_mut().__delitem__(key.into()).into()
|
||||
crate::callback::convert(py, slf.borrow_mut().__delitem__(key.into()))
|
||||
} else {
|
||||
Err(PyErr::new::<exceptions::NotImplementedError, _>(format!(
|
||||
"Item assignment not supported by {:?}",
|
||||
|
@ -280,12 +282,12 @@ mod sq_ass_item_impl {
|
|||
let slf = py.from_borrowed_ptr::<PyCell<T>>(slf);
|
||||
|
||||
if value.is_null() {
|
||||
call_mut!(slf, __delitem__; key.into())
|
||||
call_mut!(slf, __delitem__; key.into()).convert(py)
|
||||
} else {
|
||||
let value = py.from_borrowed_ptr::<PyAny>(value);
|
||||
let mut slf_ = slf.try_borrow_mut()?;
|
||||
let value = value.extract()?;
|
||||
slf_.__setitem__(key.into(), value).into()
|
||||
slf_.__setitem__(key.into(), value).convert(py)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use pyo3::class::PySequenceProtocol;
|
||||
use pyo3::exceptions::IndexError;
|
||||
use pyo3::exceptions::ValueError;
|
||||
use pyo3::exceptions::{IndexError, ValueError};
|
||||
use pyo3::prelude::*;
|
||||
use pyo3::types::{IntoPyDict, PyList};
|
||||
|
||||
|
@ -232,3 +231,38 @@ fn test_generic_list_set() {
|
|||
vec![1.to_object(py), 2.to_object(py), 3.to_object(py)]
|
||||
);
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
struct OptionList {
|
||||
#[pyo3(get, set)]
|
||||
items: Vec<Option<i64>>,
|
||||
}
|
||||
|
||||
#[pyproto]
|
||||
impl PySequenceProtocol for OptionList {
|
||||
fn __getitem__(&self, idx: isize) -> PyResult<Option<i64>> {
|
||||
match self.items.get(idx as usize) {
|
||||
Some(x) => Ok(*x),
|
||||
None => Err(PyErr::new::<IndexError, _>("Index out of bounds")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_option_list_get() {
|
||||
// Regression test for #798
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let list = PyCell::new(
|
||||
py,
|
||||
OptionList {
|
||||
items: vec![Some(1), None],
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
py_assert!(py, list, "list[0] == 1");
|
||||
py_assert!(py, list, "list[1] == None");
|
||||
py_expect_exception!(py, list, "list[2]", IndexError);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue