Replace IntoPyObject with IntoPy<PyObject>
This commit is contained in:
parent
e820d55c6f
commit
30e82a3018
|
@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
## [0.8.0]
|
||||
|
||||
### Added
|
||||
|
||||
|
@ -13,10 +13,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|||
* `py_run!` macro [#512](https://github.com/PyO3/pyo3/pull/512)
|
||||
* Use existing fields and methods before calling custom __getattr__. [#505](https://github.com/PyO3/pyo3/pull/512)
|
||||
* `PyBytes` can now be indexed just like `Vec<u8>`
|
||||
* Implement `IntoPyObject` for `PyRef` and `PyRefMut`.
|
||||
* Implement `IntoPy<PyObject>` for `PyRef` and `PyRefMut`.
|
||||
|
||||
## Removed
|
||||
|
||||
* `IntoPyObject` was replaced with `IntoPy<PyObject>`
|
||||
* `#[pyclass(subclass)]` is hidden a `unsound-subclass` feature because it's causing segmentation faults.
|
||||
|
||||
### Fixed
|
||||
|
|
|
@ -323,7 +323,7 @@ impl MyClass {
|
|||
```
|
||||
|
||||
Calls to these methods are protected by the GIL, so both `&self` and `&mut self` can be used.
|
||||
The return type must be `PyResult<T>` or `T` for some `T` that implements `IntoPyObject`;
|
||||
The return type must be `PyResult<T>` or `T` for some `T` that implements `IntoPy<PyObject>`;
|
||||
the latter is allowed if the method cannot raise Python exceptions.
|
||||
|
||||
A `Python` parameter can be specified as part of method signature, in this case the `py` argument
|
||||
|
@ -376,13 +376,13 @@ Declares a class method callable from Python.
|
|||
This may be the type object of a derived class.
|
||||
* The first parameter implicitly has type `&PyType`.
|
||||
* For details on `parameter-list`, see the documentation of `Method arguments` section.
|
||||
* The return type must be `PyResult<T>` or `T` for some `T` that implements `IntoPyObject`.
|
||||
* The return type must be `PyResult<T>` or `T` for some `T` that implements `IntoPy<PyObject>`.
|
||||
|
||||
## Static methods
|
||||
|
||||
To create a static method for a custom class, the method needs to be annotated with the
|
||||
`#[staticmethod]` attribute. The return type must be `T` or `PyResult<T>` for some `T` that implements
|
||||
`IntoPyObject`.
|
||||
`IntoPy<PyObject>`.
|
||||
|
||||
```rust
|
||||
# use pyo3::prelude::*;
|
||||
|
@ -483,7 +483,7 @@ The [`PyObjectProtocol`](https://docs.rs/pyo3/0.7.0/pyo3/class/basic/trait.PyObj
|
|||
|
||||
To customize object attribute access, define the following methods:
|
||||
|
||||
* `fn __getattr__(&self, name: FromPyObject) -> PyResult<impl IntoPyObject>`
|
||||
* `fn __getattr__(&self, name: FromPyObject) -> PyResult<impl IntoPy<PyObject>>`
|
||||
* `fn __setattr__(&mut self, name: FromPyObject, value: FromPyObject) -> PyResult<()>`
|
||||
* `fn __delattr__(&mut self, name: FromPyObject) -> PyResult<()>`
|
||||
|
||||
|
@ -589,8 +589,8 @@ struct GCTracked {} // Fails because it does not implement PyGCProtocol
|
|||
Iterators can be defined using the
|
||||
[`PyIterProtocol`](https://docs.rs/pyo3/0.7.0/pyo3/class/iter/trait.PyIterProtocol.html) trait.
|
||||
It includes two methods `__iter__` and `__next__`:
|
||||
* `fn __iter__(slf: PyRefMut<Self>) -> PyResult<impl IntoPyObject>`
|
||||
* `fn __next__(slf: PyRefMut<Self>) -> PyResult<Option<impl IntoPyObject>>`
|
||||
* `fn __iter__(slf: PyRefMut<Self>) -> PyResult<impl IntoPy<PyObject>>`
|
||||
* `fn __next__(slf: PyRefMut<Self>) -> PyResult<Option<impl IntoPy<PyObject>>>`
|
||||
|
||||
Returning `Ok(None)` from `__next__` indicates that that there are no further items.
|
||||
|
||||
|
|
|
@ -6,10 +6,10 @@ PyO3 provides some handy traits to convert between Python types and Rust types.
|
|||
|
||||
The easiest way to convert a Python object to a Rust value is using `.extract()?`.
|
||||
|
||||
## `ToPyObject` and `IntoPyObject` trait
|
||||
## `ToPyObject` trait
|
||||
|
||||
[`ToPyObject`] trait is a conversion trait that allows various objects to be
|
||||
converted into [`PyObject`][PyObject]. [`IntoPyObject`][IntoPyObject] serves the
|
||||
converted into [`PyObject`][PyObject]. `IntoPy<PyObject>` serves the
|
||||
same purpose, except that it consumes `self`.
|
||||
|
||||
## `FromPyObject` and `RefFromPyObject` trait
|
||||
|
@ -104,10 +104,9 @@ fn main() {
|
|||
|
||||
Many conversions in PyO3 can't use `std::convert::Into` because they need a GIL token. That's why the `IntoPy<T>` trait offers an `into_py` method that works just like `into`, except for taking a `Python<'_>` argument.
|
||||
|
||||
Eventually, traits such as `IntoPyObject` will be replaced by this trait and a `FromPy` trait will be added that will implement `IntoPy`, just like with `From` and `Into`.
|
||||
Eventually, traits such as `ToPyObject` will be replaced by this trait and a `FromPy` trait will be added that will implement `IntoPy`, just like with `From` and `Into`.
|
||||
|
||||
[`ToPyObject`]: https://docs.rs/pyo3/0.7.0/pyo3/trait.ToPyObject.html
|
||||
[IntoPyObject]: https://docs.rs/pyo3/0.7.0/pyo3/trait.IntoPyObject.html
|
||||
[PyObject]: https://docs.rs/pyo3/0.7.0/pyo3/struct.PyObject.html
|
||||
[PyTuple]: https://docs.rs/pyo3/0.7.0/pyo3/types/struct.PyTuple.html
|
||||
[ObjectProtocol]: https://docs.rs/pyo3/0.7.0/pyo3/trait.ObjectProtocol.html
|
||||
|
|
|
@ -376,9 +376,9 @@ fn impl_class(
|
|||
}
|
||||
}
|
||||
|
||||
impl pyo3::IntoPyObject for #cls {
|
||||
fn into_object(self, py: pyo3::Python) -> pyo3::PyObject {
|
||||
pyo3::Py::new(py, self).unwrap().into_object(py)
|
||||
impl pyo3::IntoPy<PyObject> for #cls {
|
||||
fn into_py(self, py: pyo3::Python) -> pyo3::PyObject {
|
||||
pyo3::IntoPy::into_py(pyo3::Py::new(py, self).unwrap(), py)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -337,7 +337,7 @@ pub(crate) fn impl_wrap_getter(cls: &syn::Type, name: &syn::Ident, takes_py: boo
|
|||
|
||||
match result {
|
||||
Ok(val) => {
|
||||
pyo3::IntoPyPointer::into_ptr(val.into_object(_py))
|
||||
pyo3::IntoPyPointer::into_ptr(pyo3::IntoPy::<PyObject>::into_py(val, _py))
|
||||
}
|
||||
Err(e) => {
|
||||
e.restore(_py);
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
use crate::err::PyResult;
|
||||
use crate::exceptions::OverflowError;
|
||||
use crate::ffi::{self, Py_hash_t};
|
||||
use crate::Python;
|
||||
use crate::{IntoPyObject, IntoPyPointer};
|
||||
use crate::IntoPyPointer;
|
||||
use crate::{IntoPy, PyObject, Python};
|
||||
use std::os::raw::c_int;
|
||||
use std::{isize, ptr};
|
||||
|
||||
|
@ -21,12 +21,12 @@ pub struct PyObjectCallbackConverter;
|
|||
|
||||
impl<S> CallbackConverter<S> for PyObjectCallbackConverter
|
||||
where
|
||||
S: IntoPyObject,
|
||||
S: IntoPy<PyObject>,
|
||||
{
|
||||
type R = *mut ffi::PyObject;
|
||||
|
||||
fn convert(val: S, py: Python) -> *mut ffi::PyObject {
|
||||
val.into_object(py).into_ptr()
|
||||
val.into_py(py).into_ptr()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
@ -11,14 +11,14 @@
|
|||
use crate::callback::{BoolCallbackConverter, HashConverter, PyObjectCallbackConverter};
|
||||
use crate::class::methods::PyMethodDef;
|
||||
use crate::err::{PyErr, PyResult};
|
||||
use crate::exceptions;
|
||||
use crate::ffi;
|
||||
use crate::objectprotocol::ObjectProtocol;
|
||||
use crate::type_object::PyTypeInfo;
|
||||
use crate::types::PyAny;
|
||||
use crate::FromPyObject;
|
||||
use crate::IntoPyPointer;
|
||||
use crate::Python;
|
||||
use crate::{FromPyObject, IntoPyObject};
|
||||
use crate::{exceptions, IntoPy, PyObject};
|
||||
use std::os::raw::c_int;
|
||||
use std::ptr;
|
||||
|
||||
|
@ -109,7 +109,7 @@ pub trait PyObjectProtocol<'p>: PyTypeInfo {
|
|||
|
||||
pub trait PyObjectGetAttrProtocol<'p>: PyObjectProtocol<'p> {
|
||||
type Name: FromPyObject<'p>;
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
pub trait PyObjectSetAttrProtocol<'p>: PyObjectProtocol<'p> {
|
||||
|
@ -122,16 +122,16 @@ pub trait PyObjectDelAttrProtocol<'p>: PyObjectProtocol<'p> {
|
|||
type Result: Into<PyResult<()>>;
|
||||
}
|
||||
pub trait PyObjectStrProtocol<'p>: PyObjectProtocol<'p> {
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
pub trait PyObjectReprProtocol<'p>: PyObjectProtocol<'p> {
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
pub trait PyObjectFormatProtocol<'p>: PyObjectProtocol<'p> {
|
||||
type Format: FromPyObject<'p>;
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
pub trait PyObjectHashProtocol<'p>: PyObjectProtocol<'p> {
|
||||
|
@ -141,12 +141,12 @@ pub trait PyObjectBoolProtocol<'p>: PyObjectProtocol<'p> {
|
|||
type Result: Into<PyResult<bool>>;
|
||||
}
|
||||
pub trait PyObjectBytesProtocol<'p>: PyObjectProtocol<'p> {
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
pub trait PyObjectRichcmpProtocol<'p>: PyObjectProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
|
@ -463,7 +463,7 @@ where
|
|||
Err(e) => Err(e),
|
||||
};
|
||||
match res {
|
||||
Ok(val) => val.into_object(py).into_ptr(),
|
||||
Ok(val) => val.into_py(py).into_ptr(),
|
||||
Err(e) => {
|
||||
e.restore(py);
|
||||
ptr::null_mut()
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
use crate::class::methods::PyMethodDef;
|
||||
use crate::err::PyResult;
|
||||
use crate::type_object::PyTypeInfo;
|
||||
use crate::PyObject;
|
||||
|
||||
/// Context manager interface
|
||||
#[allow(unused_variables)]
|
||||
|
@ -32,7 +33,7 @@ pub trait PyContextProtocol<'p>: PyTypeInfo {
|
|||
}
|
||||
|
||||
pub trait PyContextEnterProtocol<'p>: PyContextProtocol<'p> {
|
||||
type Success: crate::IntoPyObject;
|
||||
type Success: crate::IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
|
@ -40,7 +41,7 @@ pub trait PyContextExitProtocol<'p>: PyContextProtocol<'p> {
|
|||
type ExcType: crate::FromPyObject<'p>;
|
||||
type ExcValue: crate::FromPyObject<'p>;
|
||||
type Traceback: crate::FromPyObject<'p>;
|
||||
type Success: crate::IntoPyObject;
|
||||
type Success: crate::IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,10 +8,10 @@
|
|||
use crate::callback::{PyObjectCallbackConverter, UnitCallbackConverter};
|
||||
use crate::class::methods::PyMethodDef;
|
||||
use crate::err::PyResult;
|
||||
use crate::ffi;
|
||||
use crate::type_object::PyTypeInfo;
|
||||
use crate::types::{PyAny, PyType};
|
||||
use crate::{FromPyObject, IntoPyObject};
|
||||
use crate::FromPyObject;
|
||||
use crate::{ffi, IntoPy, PyObject};
|
||||
use std::os::raw::c_int;
|
||||
|
||||
/// Descriptor interface
|
||||
|
@ -49,7 +49,7 @@ pub trait PyDescrProtocol<'p>: PyTypeInfo {
|
|||
pub trait PyDescrGetProtocol<'p>: PyDescrProtocol<'p> {
|
||||
type Inst: FromPyObject<'p>;
|
||||
type Owner: FromPyObject<'p>;
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,12 +4,11 @@
|
|||
|
||||
use crate::callback::{CallbackConverter, PyObjectCallbackConverter};
|
||||
use crate::err::PyResult;
|
||||
use crate::ffi;
|
||||
use crate::instance::PyRefMut;
|
||||
use crate::type_object::PyTypeInfo;
|
||||
use crate::IntoPyObject;
|
||||
use crate::IntoPyPointer;
|
||||
use crate::Python;
|
||||
use crate::{ffi, IntoPy, PyObject};
|
||||
use std::ptr;
|
||||
|
||||
/// Python Iterator Interface.
|
||||
|
@ -34,12 +33,12 @@ pub trait PyIterProtocol<'p>: PyTypeInfo + Sized {
|
|||
}
|
||||
|
||||
pub trait PyIterIterProtocol<'p>: PyIterProtocol<'p> {
|
||||
type Success: crate::IntoPyObject;
|
||||
type Success: crate::IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PyIterNextProtocol<'p>: PyIterProtocol<'p> {
|
||||
type Success: crate::IntoPyObject;
|
||||
type Success: crate::IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Option<Self::Success>>>;
|
||||
}
|
||||
|
||||
|
@ -111,13 +110,13 @@ struct IterNextConverter;
|
|||
|
||||
impl<T> CallbackConverter<Option<T>> for IterNextConverter
|
||||
where
|
||||
T: IntoPyObject,
|
||||
T: IntoPy<PyObject>,
|
||||
{
|
||||
type R = *mut ffi::PyObject;
|
||||
|
||||
fn convert(val: Option<T>, py: Python) -> *mut ffi::PyObject {
|
||||
match val {
|
||||
Some(val) => val.into_object(py).into_ptr(),
|
||||
Some(val) => val.into_py(py).into_ptr(),
|
||||
None => unsafe {
|
||||
ffi::PyErr_SetNone(ffi::PyExc_StopIteration);
|
||||
ptr::null_mut()
|
||||
|
|
|
@ -21,7 +21,7 @@ macro_rules! py_unary_func {
|
|||
let py = $crate::Python::assume_gil_acquired();
|
||||
let slf = py.mut_from_borrowed_ptr::<T>(slf);
|
||||
let res = slf.$f().into();
|
||||
$crate::callback::cb_convert($conv, py, res)
|
||||
$crate::callback::cb_convert($conv, py, res.map(|x| x))
|
||||
}
|
||||
Some(wrap::<$class>)
|
||||
}};
|
||||
|
|
|
@ -6,11 +6,11 @@
|
|||
use crate::callback::{LenResultConverter, PyObjectCallbackConverter};
|
||||
use crate::class::methods::PyMethodDef;
|
||||
use crate::err::{PyErr, PyResult};
|
||||
use crate::exceptions;
|
||||
use crate::ffi;
|
||||
use crate::type_object::PyTypeInfo;
|
||||
use crate::FromPyObject;
|
||||
use crate::Python;
|
||||
use crate::{FromPyObject, IntoPyObject};
|
||||
use crate::{exceptions, IntoPy, PyObject};
|
||||
|
||||
/// Mapping interface
|
||||
#[allow(unused_variables)]
|
||||
|
@ -74,7 +74,7 @@ pub trait PyMappingLenProtocol<'p>: PyMappingProtocol<'p> {
|
|||
|
||||
pub trait PyMappingGetItemProtocol<'p>: PyMappingProtocol<'p> {
|
||||
type Key: FromPyObject<'p>;
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
|
@ -90,7 +90,7 @@ pub trait PyMappingDelItemProtocol<'p>: PyMappingProtocol<'p> {
|
|||
}
|
||||
|
||||
pub trait PyMappingIterProtocol<'p>: PyMappingProtocol<'p> {
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
|
@ -100,7 +100,7 @@ pub trait PyMappingContainsProtocol<'p>: PyMappingProtocol<'p> {
|
|||
}
|
||||
|
||||
pub trait PyMappingReversedProtocol<'p>: PyMappingProtocol<'p> {
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,9 +7,9 @@ use crate::callback::PyObjectCallbackConverter;
|
|||
use crate::class::basic::PyObjectProtocolImpl;
|
||||
use crate::class::methods::PyMethodDef;
|
||||
use crate::err::PyResult;
|
||||
use crate::ffi;
|
||||
use crate::type_object::PyTypeInfo;
|
||||
use crate::{FromPyObject, IntoPyObject};
|
||||
use crate::FromPyObject;
|
||||
use crate::{ffi, IntoPy, PyObject};
|
||||
|
||||
/// Number interface
|
||||
#[allow(unused_variables)]
|
||||
|
@ -323,56 +323,56 @@ pub trait PyNumberProtocol<'p>: PyTypeInfo {
|
|||
pub trait PyNumberAddProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Left: FromPyObject<'p>;
|
||||
type Right: FromPyObject<'p>;
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PyNumberSubProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Left: FromPyObject<'p>;
|
||||
type Right: FromPyObject<'p>;
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PyNumberMulProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Left: FromPyObject<'p>;
|
||||
type Right: FromPyObject<'p>;
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PyNumberMatmulProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Left: FromPyObject<'p>;
|
||||
type Right: FromPyObject<'p>;
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PyNumberTruedivProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Left: FromPyObject<'p>;
|
||||
type Right: FromPyObject<'p>;
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PyNumberFloordivProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Left: FromPyObject<'p>;
|
||||
type Right: FromPyObject<'p>;
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PyNumberModProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Left: FromPyObject<'p>;
|
||||
type Right: FromPyObject<'p>;
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PyNumberDivmodProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Left: FromPyObject<'p>;
|
||||
type Right: FromPyObject<'p>;
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
|
@ -380,127 +380,127 @@ pub trait PyNumberPowProtocol<'p>: PyNumberProtocol<'p> {
|
|||
type Left: FromPyObject<'p>;
|
||||
type Right: FromPyObject<'p>;
|
||||
type Modulo: FromPyObject<'p>;
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PyNumberLShiftProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Left: FromPyObject<'p>;
|
||||
type Right: FromPyObject<'p>;
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PyNumberRShiftProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Left: FromPyObject<'p>;
|
||||
type Right: FromPyObject<'p>;
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PyNumberAndProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Left: FromPyObject<'p>;
|
||||
type Right: FromPyObject<'p>;
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PyNumberXorProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Left: FromPyObject<'p>;
|
||||
type Right: FromPyObject<'p>;
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PyNumberOrProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Left: FromPyObject<'p>;
|
||||
type Right: FromPyObject<'p>;
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PyNumberRAddProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PyNumberRSubProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PyNumberRMulProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PyNumberRMatmulProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PyNumberRTruedivProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PyNumberRFloordivProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PyNumberRModProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PyNumberRDivmodProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PyNumberRPowProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Modulo: FromPyObject<'p>;
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PyNumberRLShiftProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PyNumberRRShiftProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PyNumberRAndProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PyNumberRXorProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PyNumberROrProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
|
@ -576,47 +576,47 @@ pub trait PyNumberIOrProtocol<'p>: PyNumberProtocol<'p> {
|
|||
}
|
||||
|
||||
pub trait PyNumberNegProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PyNumberPosProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PyNumberAbsProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PyNumberInvertProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PyNumberComplexProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PyNumberIntProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PyNumberFloatProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PyNumberRoundProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PyNumberIndexProtocol<'p>: PyNumberProtocol<'p> {
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ use crate::class::methods::PyMethodDef;
|
|||
use crate::err::PyResult;
|
||||
use crate::ffi;
|
||||
use crate::type_object::PyTypeInfo;
|
||||
use crate::PyObject;
|
||||
|
||||
/// Python Async/Await support interface.
|
||||
///
|
||||
|
@ -61,22 +62,22 @@ pub trait PyAsyncProtocol<'p>: PyTypeInfo {
|
|||
}
|
||||
|
||||
pub trait PyAsyncAwaitProtocol<'p>: PyAsyncProtocol<'p> {
|
||||
type Success: crate::IntoPyObject;
|
||||
type Success: crate::IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PyAsyncAiterProtocol<'p>: PyAsyncProtocol<'p> {
|
||||
type Success: crate::IntoPyObject;
|
||||
type Success: crate::IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PyAsyncAnextProtocol<'p>: PyAsyncProtocol<'p> {
|
||||
type Success: crate::IntoPyObject;
|
||||
type Success: crate::IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Option<Self::Success>>>;
|
||||
}
|
||||
|
||||
pub trait PyAsyncAenterProtocol<'p>: PyAsyncProtocol<'p> {
|
||||
type Success: crate::IntoPyObject;
|
||||
type Success: crate::IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
|
@ -84,7 +85,7 @@ pub trait PyAsyncAexitProtocol<'p>: PyAsyncProtocol<'p> {
|
|||
type ExcType: crate::FromPyObject<'p>;
|
||||
type ExcValue: crate::FromPyObject<'p>;
|
||||
type Traceback: crate::FromPyObject<'p>;
|
||||
type Success: crate::IntoPyObject;
|
||||
type Success: crate::IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
|
@ -186,23 +187,22 @@ impl<'p, T> PyAsyncAnextProtocolImpl for T where T: PyAsyncProtocol<'p> {}
|
|||
mod anext {
|
||||
use super::{PyAsyncAnextProtocol, PyAsyncAnextProtocolImpl};
|
||||
use crate::callback::CallbackConverter;
|
||||
use crate::ffi;
|
||||
use crate::IntoPyObject;
|
||||
use crate::IntoPyPointer;
|
||||
use crate::Python;
|
||||
use crate::{ffi, IntoPy, PyObject};
|
||||
use std::ptr;
|
||||
|
||||
pub struct IterANextResultConverter;
|
||||
|
||||
impl<T> CallbackConverter<Option<T>> for IterANextResultConverter
|
||||
where
|
||||
T: IntoPyObject,
|
||||
T: IntoPy<PyObject>,
|
||||
{
|
||||
type R = *mut ffi::PyObject;
|
||||
|
||||
fn convert(val: Option<T>, py: Python) -> *mut ffi::PyObject {
|
||||
match val {
|
||||
Some(val) => val.into_object(py).into_ptr(),
|
||||
Some(val) => val.into_py(py).into_ptr(),
|
||||
None => unsafe {
|
||||
ffi::PyErr_SetNone(ffi::PyExc_StopAsyncIteration);
|
||||
ptr::null_mut()
|
||||
|
|
|
@ -5,13 +5,13 @@
|
|||
|
||||
use crate::callback::{BoolCallbackConverter, LenResultConverter, PyObjectCallbackConverter};
|
||||
use crate::err::{PyErr, PyResult};
|
||||
use crate::exceptions;
|
||||
use crate::ffi;
|
||||
use crate::objectprotocol::ObjectProtocol;
|
||||
use crate::type_object::PyTypeInfo;
|
||||
use crate::types::PyAny;
|
||||
use crate::FromPyObject;
|
||||
use crate::Python;
|
||||
use crate::{FromPyObject, IntoPyObject};
|
||||
use crate::{exceptions, IntoPy, PyObject};
|
||||
use std::os::raw::c_int;
|
||||
|
||||
/// Sequence interface
|
||||
|
@ -90,7 +90,7 @@ pub trait PySequenceLenProtocol<'p>: PySequenceProtocol<'p> {
|
|||
|
||||
pub trait PySequenceGetItemProtocol<'p>: PySequenceProtocol<'p> {
|
||||
type Index: FromPyObject<'p> + From<isize>;
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
|
@ -112,22 +112,22 @@ pub trait PySequenceContainsProtocol<'p>: PySequenceProtocol<'p> {
|
|||
|
||||
pub trait PySequenceConcatProtocol<'p>: PySequenceProtocol<'p> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PySequenceRepeatProtocol<'p>: PySequenceProtocol<'p> {
|
||||
type Index: FromPyObject<'p> + From<isize>;
|
||||
type Success: IntoPyObject;
|
||||
type Success: IntoPy<PyObject>;
|
||||
type Result: Into<PyResult<Self::Success>>;
|
||||
}
|
||||
|
||||
pub trait PySequenceInplaceConcatProtocol<'p>: PySequenceProtocol<'p> + IntoPyObject {
|
||||
pub trait PySequenceInplaceConcatProtocol<'p>: PySequenceProtocol<'p> + IntoPy<PyObject> {
|
||||
type Other: FromPyObject<'p>;
|
||||
type Result: Into<PyResult<Self>>;
|
||||
}
|
||||
|
||||
pub trait PySequenceInplaceRepeatProtocol<'p>: PySequenceProtocol<'p> + IntoPyObject {
|
||||
pub trait PySequenceInplaceRepeatProtocol<'p>: PySequenceProtocol<'p> + IntoPy<PyObject> {
|
||||
type Index: FromPyObject<'p> + From<isize>;
|
||||
type Result: Into<PyResult<Self>>;
|
||||
}
|
||||
|
|
|
@ -139,7 +139,7 @@ impl<T, U> IntoPy<U> for T
|
|||
where
|
||||
U: FromPy<T>,
|
||||
{
|
||||
fn into_py(self, py: Python) -> U {
|
||||
default fn into_py(self, py: Python) -> U {
|
||||
U::from_py(self, py)
|
||||
}
|
||||
}
|
||||
|
@ -151,13 +151,6 @@ impl<T> FromPy<T> for T {
|
|||
}
|
||||
}
|
||||
|
||||
/// Conversion trait that allows various objects to be converted into `PyObject`
|
||||
/// by consuming original object.
|
||||
pub trait IntoPyObject {
|
||||
/// Converts self into a Python object. (Consumes self)
|
||||
fn into_object(self, py: Python) -> PyObject;
|
||||
}
|
||||
|
||||
/// `FromPyObject` is implemented by various types that can be extracted from
|
||||
/// a Python object reference.
|
||||
///
|
||||
|
@ -209,13 +202,13 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> IntoPyObject for Option<T>
|
||||
impl<T> IntoPy<PyObject> for Option<T>
|
||||
where
|
||||
T: IntoPyObject,
|
||||
T: IntoPy<PyObject>,
|
||||
{
|
||||
fn into_object(self, py: Python) -> PyObject {
|
||||
fn into_py(self, py: Python) -> PyObject {
|
||||
match self {
|
||||
Some(val) => val.into_object(py),
|
||||
Some(val) => val.into_py(py),
|
||||
None => py.None(),
|
||||
}
|
||||
}
|
||||
|
@ -228,29 +221,19 @@ impl ToPyObject for () {
|
|||
}
|
||||
}
|
||||
|
||||
impl IntoPyObject for () {
|
||||
fn into_object(self, py: Python) -> PyObject {
|
||||
impl IntoPy<PyObject> for () {
|
||||
fn into_py(self, py: Python) -> PyObject {
|
||||
py.None()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> IntoPyObject for &'a T
|
||||
impl<'a, T> FromPy<&'a T> for PyObject
|
||||
where
|
||||
T: AsPyPointer,
|
||||
{
|
||||
#[inline]
|
||||
fn into_object(self, py: Python) -> PyObject {
|
||||
unsafe { PyObject::from_borrowed_ptr(py, self.as_ptr()) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> IntoPyObject for &'a mut T
|
||||
where
|
||||
T: AsPyPointer,
|
||||
{
|
||||
#[inline]
|
||||
fn into_object(self, py: Python) -> PyObject {
|
||||
unsafe { PyObject::from_borrowed_ptr(py, self.as_ptr()) }
|
||||
fn from_py(other: &'a T, py: Python) -> PyObject {
|
||||
unsafe { PyObject::from_borrowed_ptr(py, other.as_ptr()) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
|
||||
use crate::err::PyResult;
|
||||
use crate::exceptions::TypeError;
|
||||
use crate::ffi;
|
||||
use crate::init_once;
|
||||
use crate::types::{PyAny, PyDict, PyModule, PyString, PyTuple};
|
||||
use crate::GILPool;
|
||||
use crate::PyTryFrom;
|
||||
use crate::Python;
|
||||
use crate::{IntoPyObject, PyTryFrom};
|
||||
use crate::{ffi, IntoPy, PyObject};
|
||||
use std::ptr;
|
||||
|
||||
/// Description of a python parameter; used for `parse_args()`.
|
||||
|
@ -157,7 +157,7 @@ pub unsafe fn make_module(
|
|||
}
|
||||
}
|
||||
|
||||
/// This trait wraps a T: IntoPyObject into PyResult<T> while PyResult<T> remains PyResult<T>.
|
||||
/// This trait wraps a T: IntoPy<PyObject> into PyResult<T> while PyResult<T> remains PyResult<T>.
|
||||
///
|
||||
/// This is necessary because proc macros run before typechecking and can't decide
|
||||
/// whether a return type is a (possibly aliased) PyResult or not. It is also quite handy because
|
||||
|
@ -166,13 +166,13 @@ pub trait IntoPyResult<T> {
|
|||
fn into_py_result(self) -> PyResult<T>;
|
||||
}
|
||||
|
||||
impl<T: IntoPyObject> IntoPyResult<T> for T {
|
||||
impl<T: IntoPy<PyObject>> IntoPyResult<T> for T {
|
||||
fn into_py_result(self) -> PyResult<T> {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: IntoPyObject> IntoPyResult<T> for PyResult<T> {
|
||||
impl<T: IntoPy<PyObject>> IntoPyResult<T> for PyResult<T> {
|
||||
fn into_py_result(self) -> PyResult<T> {
|
||||
self
|
||||
}
|
||||
|
|
12
src/err.rs
12
src/err.rs
|
@ -1,6 +1,5 @@
|
|||
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||
|
||||
use crate::exceptions;
|
||||
use crate::ffi;
|
||||
use crate::instance::Py;
|
||||
use crate::object::PyObject;
|
||||
|
@ -9,7 +8,8 @@ use crate::types::{PyAny, PyType};
|
|||
use crate::AsPyPointer;
|
||||
use crate::IntoPyPointer;
|
||||
use crate::Python;
|
||||
use crate::{IntoPyObject, ToBorrowedObject, ToPyObject};
|
||||
use crate::{exceptions, IntoPy};
|
||||
use crate::{ToBorrowedObject, ToPyObject};
|
||||
use libc::c_int;
|
||||
use std::ffi::CString;
|
||||
use std::io;
|
||||
|
@ -357,8 +357,8 @@ impl std::fmt::Debug for PyErr {
|
|||
}
|
||||
}
|
||||
|
||||
impl IntoPyObject for PyErr {
|
||||
fn into_object(self, py: Python) -> PyObject {
|
||||
impl IntoPy<PyObject> for PyErr {
|
||||
fn into_py(self, py: Python) -> PyObject {
|
||||
self.instance(py)
|
||||
}
|
||||
}
|
||||
|
@ -370,8 +370,8 @@ impl ToPyObject for PyErr {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoPyObject for &'a PyErr {
|
||||
fn into_object(self, py: Python) -> PyObject {
|
||||
impl<'a> IntoPy<PyObject> for &'a PyErr {
|
||||
fn into_py(self, py: Python) -> PyObject {
|
||||
let err = self.clone_ref(py);
|
||||
err.instance(py)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||
use crate::err::{PyErr, PyResult};
|
||||
use crate::ffi;
|
||||
use crate::gil;
|
||||
use crate::instance;
|
||||
use crate::object::PyObject;
|
||||
|
@ -8,9 +7,8 @@ use crate::objectprotocol::ObjectProtocol;
|
|||
use crate::type_object::PyTypeCreate;
|
||||
use crate::type_object::{PyTypeInfo, PyTypeObject};
|
||||
use crate::types::PyAny;
|
||||
use crate::{
|
||||
AsPyPointer, FromPyObject, FromPyPointer, IntoPyObject, IntoPyPointer, Python, ToPyObject,
|
||||
};
|
||||
use crate::{ffi, IntoPy};
|
||||
use crate::{AsPyPointer, FromPyObject, FromPyPointer, IntoPyPointer, Python, ToPyObject};
|
||||
use std::marker::PhantomData;
|
||||
use std::mem;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
@ -96,8 +94,8 @@ impl<'a, T: PyTypeInfo> ToPyObject for PyRef<'a, T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, T: PyTypeInfo> IntoPyObject for PyRef<'a, T> {
|
||||
fn into_object(self, py: Python) -> PyObject {
|
||||
impl<'a, T: PyTypeInfo> IntoPy<PyObject> for PyRef<'a, T> {
|
||||
fn into_py(self, py: Python) -> PyObject {
|
||||
self.to_object(py)
|
||||
}
|
||||
}
|
||||
|
@ -176,8 +174,8 @@ impl<'a, T: PyTypeInfo> ToPyObject for PyRefMut<'a, T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, T: PyTypeInfo> IntoPyObject for PyRefMut<'a, T> {
|
||||
fn into_object(self, py: Python) -> PyObject {
|
||||
impl<'a, T: PyTypeInfo> IntoPy<PyObject> for PyRefMut<'a, T> {
|
||||
fn into_py(self, py: Python) -> PyObject {
|
||||
self.to_object(py)
|
||||
}
|
||||
}
|
||||
|
@ -407,11 +405,11 @@ impl<T> ToPyObject for Py<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> IntoPyObject for Py<T> {
|
||||
impl<T> IntoPy<PyObject> for Py<T> {
|
||||
/// Converts `Py` instance -> PyObject.
|
||||
/// Consumes `self` without calling `Py_DECREF()`
|
||||
#[inline]
|
||||
fn into_object(self, py: Python) -> PyObject {
|
||||
fn into_py(self, py: Python) -> PyObject {
|
||||
unsafe { PyObject::from_owned_ptr(py, self.into_ptr()) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -119,8 +119,8 @@
|
|||
|
||||
pub use crate::class::*;
|
||||
pub use crate::conversion::{
|
||||
AsPyPointer, FromPy, FromPyObject, FromPyPointer, IntoPy, IntoPyObject, IntoPyPointer,
|
||||
PyTryFrom, PyTryInto, ToBorrowedObject, ToPyObject,
|
||||
AsPyPointer, FromPy, FromPyObject, FromPyPointer, IntoPy, IntoPyPointer, PyTryFrom, PyTryInto,
|
||||
ToBorrowedObject, ToPyObject,
|
||||
};
|
||||
pub use crate::err::{PyDowncastError, PyErr, PyErrArguments, PyErrValue, PyResult};
|
||||
pub use crate::gil::{init_once, GILGuard, GILPool};
|
||||
|
|
|
@ -8,9 +8,7 @@ use crate::types::{PyAny, PyDict, PyTuple};
|
|||
use crate::AsPyPointer;
|
||||
use crate::Py;
|
||||
use crate::Python;
|
||||
use crate::{
|
||||
FromPyObject, IntoPy, IntoPyObject, IntoPyPointer, PyTryFrom, ToBorrowedObject, ToPyObject,
|
||||
};
|
||||
use crate::{FromPyObject, IntoPy, IntoPyPointer, PyTryFrom, ToBorrowedObject, ToPyObject};
|
||||
use std::ptr::NonNull;
|
||||
|
||||
/// A python object
|
||||
|
@ -299,9 +297,9 @@ impl PartialEq for PyObject {
|
|||
}
|
||||
}
|
||||
|
||||
impl IntoPyObject for PyObject {
|
||||
impl IntoPy<PyObject> for PyObject {
|
||||
#[inline]
|
||||
fn into_object(self, _py: Python) -> PyObject {
|
||||
fn into_py(self, _py: Python) -> PyObject {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,9 +16,7 @@ pub use crate::instance::{AsPyRef, Py, PyRef, PyRefMut};
|
|||
pub use crate::object::PyObject;
|
||||
pub use crate::objectprotocol::ObjectProtocol;
|
||||
pub use crate::python::Python;
|
||||
pub use crate::{
|
||||
FromPy, FromPyObject, IntoPy, IntoPyObject, IntoPyPointer, PyTryFrom, PyTryInto, ToPyObject,
|
||||
};
|
||||
pub use crate::{FromPy, FromPyObject, IntoPy, IntoPyPointer, PyTryFrom, PyTryInto, ToPyObject};
|
||||
// This is only part of the prelude because we need it for the pymodule function
|
||||
pub use crate::types::PyModule;
|
||||
// This is required for the constructor
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||
use crate::ffi;
|
||||
use crate::object::PyObject;
|
||||
use crate::types::PyAny;
|
||||
use crate::AsPyPointer;
|
||||
use crate::FromPyObject;
|
||||
use crate::PyResult;
|
||||
use crate::Python;
|
||||
use crate::{IntoPyObject, PyTryFrom, ToPyObject};
|
||||
use crate::{ffi, IntoPy};
|
||||
use crate::{PyTryFrom, ToPyObject};
|
||||
|
||||
/// Represents a Python `bool`.
|
||||
#[repr(transparent)]
|
||||
|
@ -45,9 +45,9 @@ impl ToPyObject for bool {
|
|||
}
|
||||
}
|
||||
|
||||
impl IntoPyObject for bool {
|
||||
impl IntoPy<PyObject> for bool {
|
||||
#[inline]
|
||||
fn into_object(self, py: Python) -> PyObject {
|
||||
fn into_py(self, py: Python) -> PyObject {
|
||||
PyBool::new(py, self).into()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use crate::ffi;
|
||||
#[cfg(not(PyPy))]
|
||||
use crate::instance::PyNativeType;
|
||||
use crate::object::PyObject;
|
||||
use crate::AsPyPointer;
|
||||
use crate::PyObject;
|
||||
use crate::Python;
|
||||
#[cfg(not(PyPy))]
|
||||
use std::ops::*;
|
||||
|
@ -130,7 +130,7 @@ mod complex_conversion {
|
|||
use crate::err::PyErr;
|
||||
use crate::types::PyAny;
|
||||
use crate::PyResult;
|
||||
use crate::{FromPyObject, IntoPyObject, ToPyObject};
|
||||
use crate::{FromPyObject, ToPyObject};
|
||||
use num_complex::Complex;
|
||||
|
||||
impl PyComplex {
|
||||
|
@ -150,11 +150,11 @@ mod complex_conversion {
|
|||
impl ToPyObject for Complex<$float> {
|
||||
#[inline]
|
||||
fn to_object(&self, py: Python) -> PyObject {
|
||||
IntoPyObject::into_object(self.to_owned(), py)
|
||||
crate::IntoPy::<PyObject>::into_py(self.to_owned(), py)
|
||||
}
|
||||
}
|
||||
impl IntoPyObject for Complex<$float> {
|
||||
fn into_object(self, py: Python) -> PyObject {
|
||||
impl crate::IntoPy<PyObject> for Complex<$float> {
|
||||
fn into_py(self, py: Python) -> PyObject {
|
||||
unsafe {
|
||||
let raw_obj =
|
||||
ffi::PyComplex_FromDoubles(self.re as c_double, self.im as c_double);
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||
|
||||
use crate::err::{self, PyErr, PyResult};
|
||||
use crate::ffi;
|
||||
use crate::instance::PyNativeType;
|
||||
use crate::object::PyObject;
|
||||
use crate::types::{PyAny, PyList};
|
||||
|
@ -9,7 +8,8 @@ use crate::AsPyPointer;
|
|||
#[cfg(not(PyPy))]
|
||||
use crate::IntoPyPointer;
|
||||
use crate::Python;
|
||||
use crate::{IntoPyObject, ToBorrowedObject, ToPyObject};
|
||||
use crate::{ffi, IntoPy};
|
||||
use crate::{ToBorrowedObject, ToPyObject};
|
||||
use std::{cmp, collections, hash};
|
||||
|
||||
/// Represents a Python `dict`.
|
||||
|
@ -214,29 +214,29 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<K, V, H> IntoPyObject for collections::HashMap<K, V, H>
|
||||
impl<K, V, H> IntoPy<PyObject> for collections::HashMap<K, V, H>
|
||||
where
|
||||
K: hash::Hash + cmp::Eq + IntoPyObject,
|
||||
V: IntoPyObject,
|
||||
K: hash::Hash + cmp::Eq + IntoPy<PyObject>,
|
||||
V: IntoPy<PyObject>,
|
||||
H: hash::BuildHasher,
|
||||
{
|
||||
fn into_object(self, py: Python) -> PyObject {
|
||||
fn into_py(self, py: Python) -> PyObject {
|
||||
let iter = self
|
||||
.into_iter()
|
||||
.map(|(k, v)| (k.into_object(py), v.into_object(py)));
|
||||
.map(|(k, v)| (k.into_py(py), v.into_py(py)));
|
||||
IntoPyDict::into_py_dict(iter, py).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V> IntoPyObject for collections::BTreeMap<K, V>
|
||||
impl<K, V> IntoPy<PyObject> for collections::BTreeMap<K, V>
|
||||
where
|
||||
K: cmp::Eq + IntoPyObject,
|
||||
V: IntoPyObject,
|
||||
K: cmp::Eq + IntoPy<PyObject>,
|
||||
V: IntoPy<PyObject>,
|
||||
{
|
||||
fn into_object(self, py: Python) -> PyObject {
|
||||
fn into_py(self, py: Python) -> PyObject {
|
||||
let iter = self
|
||||
.into_iter()
|
||||
.map(|(k, v)| (k.into_object(py), v.into_object(py)));
|
||||
.map(|(k, v)| (k.into_py(py), v.into_py(py)));
|
||||
IntoPyDict::into_py_dict(iter, py).into()
|
||||
}
|
||||
}
|
||||
|
@ -304,12 +304,13 @@ where
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::conversion::IntoPy;
|
||||
use crate::instance::AsPyRef;
|
||||
use crate::types::dict::IntoPyDict;
|
||||
use crate::types::{PyDict, PyList, PyTuple};
|
||||
use crate::ObjectProtocol;
|
||||
use crate::Python;
|
||||
use crate::{IntoPyObject, PyTryFrom, ToPyObject};
|
||||
use crate::{ObjectProtocol, PyObject};
|
||||
use crate::{PyTryFrom, ToPyObject};
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
|
||||
#[test]
|
||||
|
@ -600,7 +601,7 @@ mod test {
|
|||
let mut map = HashMap::<i32, i32>::new();
|
||||
map.insert(1, 1);
|
||||
|
||||
let m = map.into_object(py);
|
||||
let m: PyObject = map.into_py(py);
|
||||
let py_map = <PyDict as PyTryFrom>::try_from(m.as_ref(py)).unwrap();
|
||||
|
||||
assert!(py_map.len() == 1);
|
||||
|
@ -622,14 +623,14 @@ mod test {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn test_btreemap_into_object() {
|
||||
fn test_btreemap_into_py() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let mut map = BTreeMap::<i32, i32>::new();
|
||||
map.insert(1, 1);
|
||||
|
||||
let m = map.into_object(py);
|
||||
let m: PyObject = map.into_py(py);
|
||||
let py_map = <PyDict as PyTryFrom>::try_from(m.as_ref(py)).unwrap();
|
||||
|
||||
assert!(py_map.len() == 1);
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
// based on Daniel Grunwald's https://github.com/dgrunwald/rust-cpython
|
||||
|
||||
use crate::err::PyErr;
|
||||
use crate::ffi;
|
||||
use crate::instance::PyNativeType;
|
||||
use crate::object::PyObject;
|
||||
use crate::objectprotocol::ObjectProtocol;
|
||||
|
@ -12,7 +11,8 @@ use crate::AsPyPointer;
|
|||
use crate::FromPyObject;
|
||||
use crate::PyResult;
|
||||
use crate::Python;
|
||||
use crate::{IntoPyObject, ToPyObject};
|
||||
use crate::ToPyObject;
|
||||
use crate::{ffi, IntoPy};
|
||||
use std::os::raw::c_double;
|
||||
|
||||
/// Represents a Python `float` object.
|
||||
|
@ -44,8 +44,8 @@ impl ToPyObject for f64 {
|
|||
}
|
||||
}
|
||||
|
||||
impl IntoPyObject for f64 {
|
||||
fn into_object(self, py: Python) -> PyObject {
|
||||
impl IntoPy<PyObject> for f64 {
|
||||
fn into_py(self, py: Python) -> PyObject {
|
||||
PyFloat::new(py, self).into()
|
||||
}
|
||||
}
|
||||
|
@ -70,8 +70,8 @@ impl ToPyObject for f32 {
|
|||
}
|
||||
}
|
||||
|
||||
impl IntoPyObject for f32 {
|
||||
fn into_object(self, py: Python) -> PyObject {
|
||||
impl IntoPy<PyObject> for f32 {
|
||||
fn into_py(self, py: Python) -> PyObject {
|
||||
PyFloat::new(py, f64::from(self)).into()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,10 +7,10 @@ use crate::ffi::{self, Py_ssize_t};
|
|||
use crate::instance::PyNativeType;
|
||||
use crate::object::PyObject;
|
||||
use crate::types::PyAny;
|
||||
use crate::AsPyPointer;
|
||||
use crate::IntoPyPointer;
|
||||
use crate::Python;
|
||||
use crate::{IntoPyObject, ToBorrowedObject, ToPyObject};
|
||||
use crate::{AsPyPointer, IntoPy};
|
||||
use crate::{ToBorrowedObject, ToPyObject};
|
||||
|
||||
/// Represents a Python `list`.
|
||||
#[repr(transparent)]
|
||||
|
@ -186,15 +186,15 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> IntoPyObject for Vec<T>
|
||||
impl<T> IntoPy<PyObject> for Vec<T>
|
||||
where
|
||||
T: IntoPyObject,
|
||||
T: IntoPy<PyObject>,
|
||||
{
|
||||
fn into_object(self, py: Python) -> PyObject {
|
||||
fn into_py(self, py: Python) -> PyObject {
|
||||
unsafe {
|
||||
let ptr = ffi::PyList_New(self.len() as Py_ssize_t);
|
||||
for (i, e) in self.into_iter().enumerate() {
|
||||
let obj = e.into_object(py).into_ptr();
|
||||
let obj = e.into_py(py).into_ptr();
|
||||
ffi::PyList_SetItem(ptr, i as Py_ssize_t, obj);
|
||||
}
|
||||
PyObject::from_owned_ptr_or_panic(py, ptr)
|
||||
|
|
|
@ -9,8 +9,9 @@ use crate::instance::PyNativeType;
|
|||
use crate::object::PyObject;
|
||||
use crate::types::PyAny;
|
||||
use crate::AsPyPointer;
|
||||
use crate::IntoPy;
|
||||
use crate::Python;
|
||||
use crate::{FromPyObject, IntoPyObject, ToPyObject};
|
||||
use crate::{FromPyObject, ToPyObject};
|
||||
use num_traits::cast::cast;
|
||||
use std::i64;
|
||||
use std::os::raw::c_int;
|
||||
|
@ -34,12 +35,12 @@ macro_rules! int_fits_larger_int (
|
|||
impl ToPyObject for $rust_type {
|
||||
#[inline]
|
||||
fn to_object(&self, py: Python) -> PyObject {
|
||||
(*self as $larger_type).into_object(py)
|
||||
(*self as $larger_type).into_py(py)
|
||||
}
|
||||
}
|
||||
impl IntoPyObject for $rust_type {
|
||||
fn into_object(self, py: Python) -> PyObject {
|
||||
(self as $larger_type).into_object(py)
|
||||
impl IntoPy<PyObject> for $rust_type {
|
||||
fn into_py(self, py: Python) -> PyObject {
|
||||
(self as $larger_type).into_py(py)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,11 +63,11 @@ macro_rules! int_convert_bignum (
|
|||
impl ToPyObject for $rust_type {
|
||||
#[inline]
|
||||
fn to_object(&self, py: Python) -> PyObject {
|
||||
self.into_object(py)
|
||||
(*self).into_py(py)
|
||||
}
|
||||
}
|
||||
impl IntoPyObject for $rust_type {
|
||||
fn into_object(self, py: Python) -> PyObject {
|
||||
impl IntoPy<PyObject> for $rust_type {
|
||||
fn into_py(self, py: Python) -> PyObject {
|
||||
unsafe {
|
||||
// TODO: Replace this with functions from the from_bytes family
|
||||
// Once they are stabilized
|
||||
|
@ -140,9 +141,9 @@ macro_rules! int_fits_c_long (
|
|||
}
|
||||
}
|
||||
}
|
||||
impl IntoPyObject for $rust_type {
|
||||
impl IntoPy<PyObject> for $rust_type {
|
||||
#![cfg_attr(feature="cargo-clippy", allow(clippy::cast_lossless))]
|
||||
fn into_object(self, py: Python) -> PyObject {
|
||||
fn into_py(self, py: Python) -> PyObject {
|
||||
unsafe {
|
||||
PyObject::from_owned_ptr_or_panic(py, ffi::PyLong_FromLong(self as c_long))
|
||||
}
|
||||
|
@ -181,9 +182,9 @@ macro_rules! int_convert_u64_or_i64 (
|
|||
}
|
||||
}
|
||||
}
|
||||
impl IntoPyObject for $rust_type {
|
||||
impl IntoPy<PyObject> for $rust_type {
|
||||
#[inline]
|
||||
fn into_object(self, py: Python) -> PyObject {
|
||||
fn into_py(self, py: Python) -> PyObject {
|
||||
unsafe {
|
||||
PyObject::from_owned_ptr_or_panic(py, $pylong_from_ll_or_ull(self))
|
||||
}
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||
|
||||
use crate::conversion::FromPyObject;
|
||||
use crate::conversion::{IntoPyObject, PyTryFrom, ToPyObject};
|
||||
use crate::conversion::{PyTryFrom, ToPyObject};
|
||||
use crate::err::{PyErr, PyResult};
|
||||
use crate::exceptions;
|
||||
use crate::ffi;
|
||||
use crate::instance::PyNativeType;
|
||||
use crate::object::PyObject;
|
||||
use crate::types::PyAny;
|
||||
use crate::AsPyPointer;
|
||||
use crate::Python;
|
||||
use crate::{exceptions, IntoPy};
|
||||
use std::borrow::Cow;
|
||||
use std::ops::Index;
|
||||
use std::os::raw::c_char;
|
||||
|
@ -144,9 +144,9 @@ impl ToPyObject for str {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoPyObject for &'a str {
|
||||
impl<'a> IntoPy<PyObject> for &'a str {
|
||||
#[inline]
|
||||
fn into_object(self, py: Python) -> PyObject {
|
||||
fn into_py(self, py: Python) -> PyObject {
|
||||
PyString::new(py, self).into()
|
||||
}
|
||||
}
|
||||
|
@ -169,16 +169,16 @@ impl ToPyObject for String {
|
|||
}
|
||||
}
|
||||
|
||||
impl IntoPyObject for String {
|
||||
impl IntoPy<PyObject> for String {
|
||||
#[inline]
|
||||
fn into_object(self, py: Python) -> PyObject {
|
||||
fn into_py(self, py: Python) -> PyObject {
|
||||
PyString::new(py, &self).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoPyObject for &'a String {
|
||||
impl<'a> IntoPy<PyObject> for &'a String {
|
||||
#[inline]
|
||||
fn into_object(self, py: Python) -> PyObject {
|
||||
fn into_py(self, py: Python) -> PyObject {
|
||||
PyString::new(py, self).into()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ use crate::types::PyAny;
|
|||
use crate::AsPyPointer;
|
||||
use crate::IntoPyPointer;
|
||||
use crate::Python;
|
||||
use crate::{FromPyObject, IntoPy, IntoPyObject, PyTryFrom, ToPyObject};
|
||||
use crate::{FromPyObject, IntoPy, PyTryFrom, ToPyObject};
|
||||
use std::slice;
|
||||
|
||||
/// Represents a Python `tuple` object.
|
||||
|
@ -159,21 +159,21 @@ macro_rules! tuple_conversion ({$length:expr,$(($refN:ident, $n:tt, $T:ident)),+
|
|||
}
|
||||
}
|
||||
}
|
||||
impl <$($T: IntoPyObject),+> IntoPyObject for ($($T,)+) {
|
||||
fn into_object(self, py: Python) -> PyObject {
|
||||
impl <$($T: IntoPy<PyObject>),+> IntoPy<PyObject> for ($($T,)+) {
|
||||
fn into_py(self, py: Python) -> PyObject {
|
||||
unsafe {
|
||||
let ptr = ffi::PyTuple_New($length);
|
||||
$(ffi::PyTuple_SetItem(ptr, $n, self.$n.into_object(py).into_ptr());)+
|
||||
$(ffi::PyTuple_SetItem(ptr, $n, self.$n.into_py(py).into_ptr());)+
|
||||
PyObject::from_owned_ptr_or_panic(py, ptr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl <$($T: IntoPyObject),+> IntoPy<Py<PyTuple>> for ($($T,)+) {
|
||||
impl <$($T: IntoPy<PyObject>),+> IntoPy<Py<PyTuple>> for ($($T,)+) {
|
||||
fn into_py(self, py: Python) -> Py<PyTuple> {
|
||||
unsafe {
|
||||
let ptr = ffi::PyTuple_New($length);
|
||||
$(ffi::PyTuple_SetItem(ptr, $n, self.$n.into_object(py).into_ptr());)+
|
||||
$(ffi::PyTuple_SetItem(ptr, $n, self.$n.into_py(py).into_ptr());)+
|
||||
Py::from_owned_ptr_or_panic(ptr)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -391,11 +391,11 @@ impl<'p> PyMappingProtocol<'p> for Test {
|
|||
if let Ok(slice) = idx.cast_as::<PySlice>() {
|
||||
let indices = slice.indices(1000)?;
|
||||
if indices.start == 100 && indices.stop == 200 && indices.step == 1 {
|
||||
return Ok("slice".into_object(gil.python()));
|
||||
return Ok("slice".into_py(gil.python()));
|
||||
}
|
||||
} else if let Ok(idx) = idx.extract::<isize>() {
|
||||
if idx == 1 {
|
||||
return Ok("int".into_object(gil.python()));
|
||||
return Ok("int".into_py(gil.python()));
|
||||
}
|
||||
}
|
||||
Err(PyErr::new::<ValueError, _>("error"))
|
||||
|
|
|
@ -94,7 +94,7 @@ impl Drop for ClassWithDrop {
|
|||
let py = Python::assume_gil_acquired();
|
||||
|
||||
let _empty1: Py<PyTuple> = FromPy::from_py(PyTuple::empty(py), py);
|
||||
let _empty2 = PyTuple::empty(py).into_object(py);
|
||||
let _empty2: PyObject = PyTuple::empty(py).into_py(py);
|
||||
let _empty3: &PyAny = py.from_owned_ptr(ffi::PyTuple_New(0));
|
||||
}
|
||||
}
|
||||
|
@ -110,9 +110,9 @@ fn create_pointers_in_drop() {
|
|||
{
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let empty = PyTuple::empty(py).into_object(py);
|
||||
let empty: PyObject = PyTuple::empty(py).into_py(py);
|
||||
ptr = empty.as_ptr();
|
||||
// substract 2, because `PyTuple::empty(py).into_object(py)` increases the refcnt by 2
|
||||
// substract 2, because `PyTuple::empty(py).into_py(py)` increases the refcnt by 2
|
||||
cnt = empty.get_refcnt() - 2;
|
||||
let inst = Py::new(py, ClassWithDrop {}).unwrap();
|
||||
drop(inst);
|
||||
|
|
|
@ -84,7 +84,7 @@ fn reader() -> Reader {
|
|||
fn test_nested_iter() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let reader = reader().into_object(py);
|
||||
let reader: PyObject = reader().into_py(py);
|
||||
py_assert!(
|
||||
py,
|
||||
reader,
|
||||
|
@ -96,7 +96,7 @@ fn test_nested_iter() {
|
|||
fn test_clone_ref() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let reader = reader().into_object(py);
|
||||
let reader: PyObject = reader().into_py(py);
|
||||
py_assert!(py, reader, "reader == reader.clone_ref()");
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue