Use PyMethodsImpl instead of *ProtocolImpl::methods
This commit is contained in:
parent
da22eecb5f
commit
69dba08b01
|
@ -24,11 +24,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
||||||
- The `GILGuard` returned from `Python::acquire_gil` will now only assume responsiblity for freeing owned references on drop if no other `GILPool` or `GILGuard` exists. This ensures that multiple calls to the safe api `Python::acquire_gil` cannot lead to dangling references. [#893](https://github.com/PyO3/pyo3/pull/893)
|
- The `GILGuard` returned from `Python::acquire_gil` will now only assume responsiblity for freeing owned references on drop if no other `GILPool` or `GILGuard` exists. This ensures that multiple calls to the safe api `Python::acquire_gil` cannot lead to dangling references. [#893](https://github.com/PyO3/pyo3/pull/893)
|
||||||
- The trait `ObjectProtocol` has been removed, and all the methods from the trait have been moved to `PyAny`. [#911](https://github.com/PyO3/pyo3/pull/911)
|
- The trait `ObjectProtocol` has been removed, and all the methods from the trait have been moved to `PyAny`. [#911](https://github.com/PyO3/pyo3/pull/911)
|
||||||
- The exception to this is `ObjectProtocol::None`, which has simply been removed. Use `Python::None` instead.
|
- The exception to this is `ObjectProtocol::None`, which has simply been removed. Use `Python::None` instead.
|
||||||
|
- No `#![feature(specialization)]` in user code. [#917](https://github.com/PyO3/pyo3/pull/917)
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
- `PyMethodsProtocol` is now renamed to `PyMethodsImpl` and hidden. [#889](https://github.com/PyO3/pyo3/pull/889)
|
- `PyMethodsProtocol` is now renamed to `PyMethodsImpl` and hidden. [#889](https://github.com/PyO3/pyo3/pull/889)
|
||||||
- `num-traits` is no longer a dependency. [#895](https://github.com/PyO3/pyo3/pull/895)
|
- `num-traits` is no longer a dependency. [#895](https://github.com/PyO3/pyo3/pull/895)
|
||||||
- `ObjectProtocol`. [#911](https://github.com/PyO3/pyo3/pull/911)
|
- `ObjectProtocol`. [#911](https://github.com/PyO3/pyo3/pull/911)
|
||||||
|
- All `*ProtocolImpl` traits. [#917](https://github.com/PyO3/pyo3/pull/917)
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- `__radd__` and other `__r*__` methods now correctly work with operators. [#839](https://github.com/PyO3/pyo3/pull/839)
|
- `__radd__` and other `__r*__` methods now correctly work with operators. [#839](https://github.com/PyO3/pyo3/pull/839)
|
||||||
|
|
|
@ -17,76 +17,7 @@ struct MyClass {
|
||||||
The above example generates implementations for [`PyTypeInfo`], [`PyTypeObject`],
|
The above example generates implementations for [`PyTypeInfo`], [`PyTypeObject`],
|
||||||
and [`PyClass`] for `MyClass`.
|
and [`PyClass`] for `MyClass`.
|
||||||
|
|
||||||
Specifically, the following implementation is generated:
|
If you curious what `#[pyclass]` generates, see [How methods are implemented](#how-methods-are-implemented) section.
|
||||||
|
|
||||||
```rust
|
|
||||||
use pyo3::prelude::*;
|
|
||||||
|
|
||||||
/// Class for demonstration
|
|
||||||
struct MyClass {
|
|
||||||
num: i32,
|
|
||||||
debug: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl pyo3::pyclass::PyClassAlloc for MyClass {}
|
|
||||||
|
|
||||||
unsafe impl pyo3::PyTypeInfo for MyClass {
|
|
||||||
type Type = MyClass;
|
|
||||||
type BaseType = PyAny;
|
|
||||||
type BaseLayout = pyo3::pycell::PyCellBase<PyAny>;
|
|
||||||
type Layout = PyCell<Self>;
|
|
||||||
type Initializer = PyClassInitializer<Self>;
|
|
||||||
type AsRefTarget = PyCell<Self>;
|
|
||||||
|
|
||||||
const NAME: &'static str = "MyClass";
|
|
||||||
const MODULE: Option<&'static str> = None;
|
|
||||||
const DESCRIPTION: &'static str = "Class for demonstration";
|
|
||||||
const FLAGS: usize = 0;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn type_object() -> &'static pyo3::ffi::PyTypeObject {
|
|
||||||
use pyo3::type_object::LazyStaticType;
|
|
||||||
static TYPE_OBJECT: LazyStaticType = LazyStaticType::new();
|
|
||||||
TYPE_OBJECT.get_or_init::<Self>()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl pyo3::pyclass::PyClass for MyClass {
|
|
||||||
type Dict = pyo3::pyclass_slots::PyClassDummySlot;
|
|
||||||
type WeakRef = pyo3::pyclass_slots::PyClassDummySlot;
|
|
||||||
type BaseNativeType = PyAny;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl pyo3::IntoPy<PyObject> for MyClass {
|
|
||||||
fn into_py(self, py: pyo3::Python) -> pyo3::PyObject {
|
|
||||||
pyo3::IntoPy::into_py(pyo3::Py::new(py, self).unwrap(), py)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Pyo3MethodsInventoryForMyClass {
|
|
||||||
methods: &'static [pyo3::class::PyMethodDefType],
|
|
||||||
}
|
|
||||||
|
|
||||||
impl pyo3::class::methods::PyMethodsInventory for Pyo3MethodsInventoryForMyClass {
|
|
||||||
fn new(methods: &'static [pyo3::class::PyMethodDefType]) -> Self {
|
|
||||||
Self { methods }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_methods(&self) -> &'static [pyo3::class::PyMethodDefType] {
|
|
||||||
self.methods
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl pyo3::class::methods::PyMethodsImpl for MyClass {
|
|
||||||
type Methods = Pyo3MethodsInventoryForMyClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
pyo3::inventory::collect!(Pyo3MethodsInventoryForMyClass);
|
|
||||||
# let gil = Python::acquire_gil();
|
|
||||||
# let py = gil.python();
|
|
||||||
# let cls = py.get_type::<MyClass>();
|
|
||||||
# pyo3::py_run!(py, cls, "assert cls.__name__ == 'MyClass'")
|
|
||||||
```
|
|
||||||
|
|
||||||
## Adding the class to a module
|
## Adding the class to a module
|
||||||
|
|
||||||
|
@ -944,7 +875,77 @@ pyclass dependent on whether there is an impl block, we'd need to implement the
|
||||||
`#[pyclass]` and override the implementation in `#[pymethods]`, which is to the best of my knowledge
|
`#[pyclass]` and override the implementation in `#[pymethods]`, which is to the best of my knowledge
|
||||||
only possible with the specialization feature, which can't be used on stable.
|
only possible with the specialization feature, which can't be used on stable.
|
||||||
|
|
||||||
To escape this we use [inventory](https://github.com/dtolnay/inventory), which allows us to collect `impl`s from arbitrary source code by exploiting some binary trick. See [inventory: how it works](https://github.com/dtolnay/inventory#how-it-works) and `pyo3_derive_backend::py_class::impl_inventory` for more details.
|
To escape this we use [inventory](https://github.com/dtolnay/inventory),
|
||||||
|
which allows us to collect `impl`s from arbitrary source code by exploiting some binary trick.
|
||||||
|
See [inventory: how it works](https://github.com/dtolnay/inventory#how-it-works) and `pyo3_derive_backend::py_class` for more details.
|
||||||
|
|
||||||
|
Specifically, the following implementation is generated:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use pyo3::prelude::*;
|
||||||
|
|
||||||
|
/// Class for demonstration
|
||||||
|
struct MyClass {
|
||||||
|
num: i32,
|
||||||
|
debug: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl pyo3::pyclass::PyClassAlloc for MyClass {}
|
||||||
|
|
||||||
|
unsafe impl pyo3::PyTypeInfo for MyClass {
|
||||||
|
type Type = MyClass;
|
||||||
|
type BaseType = PyAny;
|
||||||
|
type BaseLayout = pyo3::pycell::PyCellBase<PyAny>;
|
||||||
|
type Layout = PyCell<Self>;
|
||||||
|
type Initializer = PyClassInitializer<Self>;
|
||||||
|
type AsRefTarget = PyCell<Self>;
|
||||||
|
|
||||||
|
const NAME: &'static str = "MyClass";
|
||||||
|
const MODULE: Option<&'static str> = None;
|
||||||
|
const DESCRIPTION: &'static str = "Class for demonstration";
|
||||||
|
const FLAGS: usize = 0;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn type_object() -> &'static pyo3::ffi::PyTypeObject {
|
||||||
|
use pyo3::type_object::LazyStaticType;
|
||||||
|
static TYPE_OBJECT: LazyStaticType = LazyStaticType::new();
|
||||||
|
TYPE_OBJECT.get_or_init::<Self>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl pyo3::pyclass::PyClass for MyClass {
|
||||||
|
type Dict = pyo3::pyclass_slots::PyClassDummySlot;
|
||||||
|
type WeakRef = pyo3::pyclass_slots::PyClassDummySlot;
|
||||||
|
type BaseNativeType = PyAny;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl pyo3::IntoPy<PyObject> for MyClass {
|
||||||
|
fn into_py(self, py: pyo3::Python) -> pyo3::PyObject {
|
||||||
|
pyo3::IntoPy::into_py(pyo3::Py::new(py, self).unwrap(), py)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Pyo3MethodsInventoryForMyClass {
|
||||||
|
methods: &'static [pyo3::class::PyMethodDefType],
|
||||||
|
}
|
||||||
|
impl pyo3::class::methods::PyMethodsInventory for Pyo3MethodsInventoryForMyClass {
|
||||||
|
fn new(methods: &'static [pyo3::class::PyMethodDefType]) -> Self {
|
||||||
|
Self { methods }
|
||||||
|
}
|
||||||
|
fn get(&self) -> &'static [pyo3::class::PyMethodDefType] {
|
||||||
|
self.methods
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl pyo3::class::methods::PyMethodsImpl for MyClass {
|
||||||
|
type Methods = Pyo3MethodsInventoryForMyClass;
|
||||||
|
}
|
||||||
|
pyo3::inventory::collect!(Pyo3MethodsInventoryForMyClass);
|
||||||
|
# let gil = Python::acquire_gil();
|
||||||
|
# let py = gil.python();
|
||||||
|
# let cls = py.get_type::<MyClass>();
|
||||||
|
# pyo3::py_run!(py, cls, "assert cls.__name__ == 'MyClass'")
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
[`GILGuard`]: https://docs.rs/pyo3/latest/pyo3/struct.GILGuard.html
|
[`GILGuard`]: https://docs.rs/pyo3/latest/pyo3/struct.GILGuard.html
|
||||||
[`PyGCProtocol`]: https://docs.rs/pyo3/latest/pyo3/class/gc/trait.PyGCProtocol.html
|
[`PyGCProtocol`]: https://docs.rs/pyo3/latest/pyo3/class/gc/trait.PyGCProtocol.html
|
||||||
|
|
|
@ -208,11 +208,9 @@ fn parse_descriptors(item: &mut syn::Field) -> syn::Result<Vec<FnType>> {
|
||||||
Ok(descs)
|
Ok(descs)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The orphan rule disallows using a generic inventory struct, so we create the whole boilerplate
|
/// To allow multiple #[pymethods]/#[pyproto] block, we define inventory types.
|
||||||
/// once per class
|
fn impl_methods_inventory(cls: &syn::Ident) -> TokenStream {
|
||||||
fn impl_inventory(cls: &syn::Ident) -> TokenStream {
|
// Try to build a unique type for better error messages
|
||||||
// Try to build a unique type that gives a hint about it's function when
|
|
||||||
// it comes up in error messages
|
|
||||||
let name = format!("Pyo3MethodsInventoryFor{}", cls);
|
let name = format!("Pyo3MethodsInventoryFor{}", cls);
|
||||||
let inventory_cls = syn::Ident::new(&name, Span::call_site());
|
let inventory_cls = syn::Ident::new(&name, Span::call_site());
|
||||||
|
|
||||||
|
@ -221,15 +219,11 @@ fn impl_inventory(cls: &syn::Ident) -> TokenStream {
|
||||||
pub struct #inventory_cls {
|
pub struct #inventory_cls {
|
||||||
methods: &'static [pyo3::class::PyMethodDefType],
|
methods: &'static [pyo3::class::PyMethodDefType],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl pyo3::class::methods::PyMethodsInventory for #inventory_cls {
|
impl pyo3::class::methods::PyMethodsInventory for #inventory_cls {
|
||||||
fn new(methods: &'static [pyo3::class::PyMethodDefType]) -> Self {
|
fn new(methods: &'static [pyo3::class::PyMethodDefType]) -> Self {
|
||||||
Self {
|
Self { methods }
|
||||||
methods
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
fn get(&self) -> &'static [pyo3::class::PyMethodDefType] {
|
||||||
fn get_methods(&self) -> &'static [pyo3::class::PyMethodDefType] {
|
|
||||||
self.methods
|
self.methods
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -345,7 +339,7 @@ fn impl_class(
|
||||||
quote! {}
|
quote! {}
|
||||||
};
|
};
|
||||||
|
|
||||||
let inventory_impl = impl_inventory(&cls);
|
let impl_inventory = impl_methods_inventory(&cls);
|
||||||
|
|
||||||
let base = &attr.base;
|
let base = &attr.base;
|
||||||
let flags = &attr.flags;
|
let flags = &attr.flags;
|
||||||
|
@ -418,7 +412,7 @@ fn impl_class(
|
||||||
|
|
||||||
#into_pyobject
|
#into_pyobject
|
||||||
|
|
||||||
#inventory_impl
|
#impl_inventory
|
||||||
|
|
||||||
#extra
|
#extra
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ pub fn build_py_proto(ast: &mut syn::ItemImpl) -> syn::Result<TokenStream> {
|
||||||
));
|
));
|
||||||
};
|
};
|
||||||
|
|
||||||
let tokens = impl_proto_impl(&ast.self_ty, &mut ast.items, proto);
|
let tokens = impl_proto_impl(&ast.self_ty, &mut ast.items, proto)?;
|
||||||
|
|
||||||
// attach lifetime
|
// attach lifetime
|
||||||
let mut seg = path.segments.pop().unwrap().into_value();
|
let mut seg = path.segments.pop().unwrap().into_value();
|
||||||
|
@ -57,53 +57,54 @@ fn impl_proto_impl(
|
||||||
ty: &syn::Type,
|
ty: &syn::Type,
|
||||||
impls: &mut Vec<syn::ImplItem>,
|
impls: &mut Vec<syn::ImplItem>,
|
||||||
proto: &defs::Proto,
|
proto: &defs::Proto,
|
||||||
) -> TokenStream {
|
) -> syn::Result<TokenStream> {
|
||||||
let mut tokens = TokenStream::new();
|
let mut trait_impls = TokenStream::new();
|
||||||
let mut py_methods = Vec::new();
|
let mut py_methods = Vec::new();
|
||||||
|
|
||||||
for iimpl in impls.iter_mut() {
|
for iimpl in impls.iter_mut() {
|
||||||
if let syn::ImplItem::Method(ref mut met) = iimpl {
|
if let syn::ImplItem::Method(ref mut met) = iimpl {
|
||||||
if let Some(m) = proto.get_proto(&met.sig.ident) {
|
if let Some(m) = proto.get_proto(&met.sig.ident) {
|
||||||
impl_method_proto(ty, &mut met.sig, m).to_tokens(&mut tokens);
|
impl_method_proto(ty, &mut met.sig, m).to_tokens(&mut trait_impls);
|
||||||
}
|
}
|
||||||
if let Some(m) = proto.get_method(&met.sig.ident) {
|
if let Some(m) = proto.get_method(&met.sig.ident) {
|
||||||
let name = &met.sig.ident;
|
let name = &met.sig.ident;
|
||||||
let proto: syn::Path = syn::parse_str(m.proto).unwrap();
|
let fn_spec = FnSpec::parse(&met.sig, &mut met.attrs, false)?;
|
||||||
|
let method = pymethod::impl_proto_wrap(ty, &fn_spec);
|
||||||
let fn_spec = match FnSpec::parse(&met.sig, &mut met.attrs, false) {
|
|
||||||
Ok(fn_spec) => fn_spec,
|
|
||||||
Err(err) => return err.to_compile_error(),
|
|
||||||
};
|
|
||||||
let meth = pymethod::impl_proto_wrap(ty, &fn_spec);
|
|
||||||
let coexist = if m.can_coexist {
|
let coexist = if m.can_coexist {
|
||||||
|
// We need METH_COEXIST here to prevent __add__ from overriding __radd__
|
||||||
quote!(pyo3::ffi::METH_COEXIST)
|
quote!(pyo3::ffi::METH_COEXIST)
|
||||||
} else {
|
} else {
|
||||||
quote!(0)
|
quote!(0)
|
||||||
};
|
};
|
||||||
|
// TODO(kngwyu): doc
|
||||||
py_methods.push(quote! {
|
py_methods.push(quote! {
|
||||||
impl #proto for #ty
|
pyo3::class::PyMethodDefType::Method({
|
||||||
{
|
#method
|
||||||
#[inline]
|
pyo3::class::PyMethodDef {
|
||||||
fn #name() -> Option<pyo3::class::methods::PyMethodDef> {
|
ml_name: stringify!(#name),
|
||||||
#meth
|
ml_meth: pyo3::class::PyMethodType::PyCFunctionWithKeywords(__wrap),
|
||||||
|
ml_flags: pyo3::ffi::METH_VARARGS | pyo3::ffi::METH_KEYWORDS | #coexist,
|
||||||
Some(pyo3::class::PyMethodDef {
|
ml_doc: ""
|
||||||
ml_name: stringify!(#name),
|
|
||||||
ml_meth: pyo3::class::PyMethodType::PyCFunctionWithKeywords(__wrap),
|
|
||||||
// We need METH_COEXIST here to prevent __add__ from overriding __radd__
|
|
||||||
ml_flags: pyo3::ffi::METH_VARARGS | pyo3::ffi::METH_KEYWORDS | #coexist,
|
|
||||||
ml_doc: ""
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
quote! {
|
if py_methods.is_empty() {
|
||||||
#tokens
|
return Ok(quote! { #trait_impls });
|
||||||
|
|
||||||
#(#py_methods)*
|
|
||||||
}
|
}
|
||||||
|
let inventory_submission = quote! {
|
||||||
|
pyo3::inventory::submit! {
|
||||||
|
#![crate = pyo3] {
|
||||||
|
type ProtoInventory = <#ty as pyo3::class::methods::PyMethodsImpl>::Methods;
|
||||||
|
<ProtoInventory as pyo3::class::methods::PyMethodsInventory>::new(&[#(#py_methods),*])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Ok(quote! {
|
||||||
|
#trait_impls
|
||||||
|
#inventory_submission
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
//! [typeobj docs](https://docs.python.org/3/c-api/typeobj.html)
|
//! [typeobj docs](https://docs.python.org/3/c-api/typeobj.html)
|
||||||
|
|
||||||
use crate::callback::HashCallbackOutput;
|
use crate::callback::HashCallbackOutput;
|
||||||
use crate::class::methods::PyMethodDef;
|
|
||||||
use crate::{
|
use crate::{
|
||||||
exceptions, ffi, FromPyObject, IntoPy, PyAny, PyCell, PyClass, PyErr, PyObject, PyResult,
|
exceptions, ffi, FromPyObject, IntoPy, PyAny, PyCell, PyClass, PyErr, PyObject, PyResult,
|
||||||
};
|
};
|
||||||
|
@ -145,15 +144,11 @@ pub trait PyObjectRichcmpProtocol<'p>: PyObjectProtocol<'p> {
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub trait PyObjectProtocolImpl {
|
pub trait PyObjectProtocolImpl {
|
||||||
fn methods() -> Vec<PyMethodDef>;
|
|
||||||
fn tp_as_object(_type_object: &mut ffi::PyTypeObject);
|
fn tp_as_object(_type_object: &mut ffi::PyTypeObject);
|
||||||
fn nb_bool_fn() -> Option<ffi::inquiry>;
|
fn nb_bool_fn() -> Option<ffi::inquiry>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> PyObjectProtocolImpl for T {
|
impl<T> PyObjectProtocolImpl for T {
|
||||||
default fn methods() -> Vec<PyMethodDef> {
|
|
||||||
Vec::new()
|
|
||||||
}
|
|
||||||
default fn tp_as_object(_type_object: &mut ffi::PyTypeObject) {}
|
default fn tp_as_object(_type_object: &mut ffi::PyTypeObject) {}
|
||||||
default fn nb_bool_fn() -> Option<ffi::inquiry> {
|
default fn nb_bool_fn() -> Option<ffi::inquiry> {
|
||||||
None
|
None
|
||||||
|
@ -164,20 +159,6 @@ impl<'p, T> PyObjectProtocolImpl for T
|
||||||
where
|
where
|
||||||
T: PyObjectProtocol<'p>,
|
T: PyObjectProtocol<'p>,
|
||||||
{
|
{
|
||||||
fn methods() -> Vec<PyMethodDef> {
|
|
||||||
let mut methods = Vec::new();
|
|
||||||
|
|
||||||
if let Some(def) = <Self as FormatProtocolImpl>::__format__() {
|
|
||||||
methods.push(def)
|
|
||||||
}
|
|
||||||
if let Some(def) = <Self as BytesProtocolImpl>::__bytes__() {
|
|
||||||
methods.push(def)
|
|
||||||
}
|
|
||||||
if let Some(def) = <Self as UnicodeProtocolImpl>::__unicode__() {
|
|
||||||
methods.push(def)
|
|
||||||
}
|
|
||||||
methods
|
|
||||||
}
|
|
||||||
fn tp_as_object(type_object: &mut ffi::PyTypeObject) {
|
fn tp_as_object(type_object: &mut ffi::PyTypeObject) {
|
||||||
type_object.tp_str = Self::tp_str();
|
type_object.tp_str = Self::tp_str();
|
||||||
type_object.tp_repr = Self::tp_repr();
|
type_object.tp_repr = Self::tp_repr();
|
||||||
|
@ -373,45 +354,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub trait FormatProtocolImpl {
|
|
||||||
fn __format__() -> Option<PyMethodDef>;
|
|
||||||
}
|
|
||||||
impl<'p, T> FormatProtocolImpl for T
|
|
||||||
where
|
|
||||||
T: PyObjectProtocol<'p>,
|
|
||||||
{
|
|
||||||
default fn __format__() -> Option<PyMethodDef> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub trait BytesProtocolImpl {
|
|
||||||
fn __bytes__() -> Option<PyMethodDef>;
|
|
||||||
}
|
|
||||||
impl<'p, T> BytesProtocolImpl for T
|
|
||||||
where
|
|
||||||
T: PyObjectProtocol<'p>,
|
|
||||||
{
|
|
||||||
default fn __bytes__() -> Option<PyMethodDef> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub trait UnicodeProtocolImpl {
|
|
||||||
fn __unicode__() -> Option<PyMethodDef>;
|
|
||||||
}
|
|
||||||
impl<'p, T> UnicodeProtocolImpl for T
|
|
||||||
where
|
|
||||||
T: PyObjectProtocol<'p>,
|
|
||||||
{
|
|
||||||
default fn __unicode__() -> Option<PyMethodDef> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
trait HashProtocolImpl {
|
trait HashProtocolImpl {
|
||||||
fn tp_hash() -> Option<ffi::hashfunc>;
|
fn tp_hash() -> Option<ffi::hashfunc>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
//! Trait and support implementation for context manager api
|
//! Trait and support implementation for context manager api
|
||||||
//!
|
//!
|
||||||
|
|
||||||
use crate::class::methods::PyMethodDef;
|
|
||||||
use crate::err::PyResult;
|
use crate::err::PyResult;
|
||||||
use crate::{PyClass, PyObject};
|
use crate::{PyClass, PyObject};
|
||||||
|
|
||||||
|
@ -43,61 +42,3 @@ pub trait PyContextExitProtocol<'p>: PyContextProtocol<'p> {
|
||||||
type Success: crate::IntoPy<PyObject>;
|
type Success: crate::IntoPy<PyObject>;
|
||||||
type Result: Into<PyResult<Self::Success>>;
|
type Result: Into<PyResult<Self::Success>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub trait PyContextProtocolImpl {
|
|
||||||
fn methods() -> Vec<PyMethodDef>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> PyContextProtocolImpl for T {
|
|
||||||
default fn methods() -> Vec<PyMethodDef> {
|
|
||||||
Vec::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'p, T> PyContextProtocolImpl for T
|
|
||||||
where
|
|
||||||
T: PyContextProtocol<'p>,
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn methods() -> Vec<PyMethodDef> {
|
|
||||||
let mut methods = Vec::new();
|
|
||||||
|
|
||||||
if let Some(def) = <Self as PyContextEnterProtocolImpl>::__enter__() {
|
|
||||||
methods.push(def)
|
|
||||||
}
|
|
||||||
if let Some(def) = <Self as PyContextExitProtocolImpl>::__exit__() {
|
|
||||||
methods.push(def)
|
|
||||||
}
|
|
||||||
|
|
||||||
methods
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub trait PyContextEnterProtocolImpl {
|
|
||||||
fn __enter__() -> Option<PyMethodDef>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'p, T> PyContextEnterProtocolImpl for T
|
|
||||||
where
|
|
||||||
T: PyContextProtocol<'p>,
|
|
||||||
{
|
|
||||||
default fn __enter__() -> Option<PyMethodDef> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub trait PyContextExitProtocolImpl {
|
|
||||||
fn __exit__() -> Option<PyMethodDef>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'p, T> PyContextExitProtocolImpl for T
|
|
||||||
where
|
|
||||||
T: PyContextProtocol<'p>,
|
|
||||||
{
|
|
||||||
default fn __exit__() -> Option<PyMethodDef> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -123,14 +123,10 @@ impl<'p, T> PyDescrSetNameProtocolImpl for T where T: PyDescrProtocol<'p> {}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub trait PyDescrProtocolImpl {
|
pub trait PyDescrProtocolImpl {
|
||||||
fn methods() -> Vec<PyMethodDef>;
|
|
||||||
fn tp_as_descr(_type_object: &mut ffi::PyTypeObject);
|
fn tp_as_descr(_type_object: &mut ffi::PyTypeObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> PyDescrProtocolImpl for T {
|
impl<T> PyDescrProtocolImpl for T {
|
||||||
default fn methods() -> Vec<PyMethodDef> {
|
|
||||||
Vec::new()
|
|
||||||
}
|
|
||||||
default fn tp_as_descr(_type_object: &mut ffi::PyTypeObject) {}
|
default fn tp_as_descr(_type_object: &mut ffi::PyTypeObject) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,9 +134,6 @@ impl<'p, T> PyDescrProtocolImpl for T
|
||||||
where
|
where
|
||||||
T: PyDescrProtocol<'p>,
|
T: PyDescrProtocol<'p>,
|
||||||
{
|
{
|
||||||
fn methods() -> Vec<PyMethodDef> {
|
|
||||||
Vec::new()
|
|
||||||
}
|
|
||||||
fn tp_as_descr(type_object: &mut ffi::PyTypeObject) {
|
fn tp_as_descr(type_object: &mut ffi::PyTypeObject) {
|
||||||
type_object.tp_descr_get = Self::tp_descr_get();
|
type_object.tp_descr_get = Self::tp_descr_get();
|
||||||
type_object.tp_descr_set = Self::tp_descr_set();
|
type_object.tp_descr_set = Self::tp_descr_set();
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
//! Python Mapping Interface
|
//! Python Mapping Interface
|
||||||
//! Trait and support implementation for implementing mapping support
|
//! Trait and support implementation for implementing mapping support
|
||||||
|
|
||||||
use crate::class::methods::PyMethodDef;
|
|
||||||
use crate::err::{PyErr, PyResult};
|
use crate::err::{PyErr, PyResult};
|
||||||
use crate::{exceptions, ffi, FromPyObject, IntoPy, PyClass, PyObject};
|
use crate::{exceptions, ffi, FromPyObject, IntoPy, PyClass, PyObject};
|
||||||
|
|
||||||
|
@ -78,16 +77,12 @@ pub trait PyMappingReversedProtocol<'p>: PyMappingProtocol<'p> {
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub trait PyMappingProtocolImpl {
|
pub trait PyMappingProtocolImpl {
|
||||||
fn tp_as_mapping() -> Option<ffi::PyMappingMethods>;
|
fn tp_as_mapping() -> Option<ffi::PyMappingMethods>;
|
||||||
fn methods() -> Vec<PyMethodDef>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> PyMappingProtocolImpl for T {
|
impl<T> PyMappingProtocolImpl for T {
|
||||||
default fn tp_as_mapping() -> Option<ffi::PyMappingMethods> {
|
default fn tp_as_mapping() -> Option<ffi::PyMappingMethods> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
default fn methods() -> Vec<PyMethodDef> {
|
|
||||||
Vec::new()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'p, T> PyMappingProtocolImpl for T
|
impl<'p, T> PyMappingProtocolImpl for T
|
||||||
|
@ -108,17 +103,6 @@ where
|
||||||
mp_ass_subscript: f,
|
mp_ass_subscript: f,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn methods() -> Vec<PyMethodDef> {
|
|
||||||
let mut methods = Vec::new();
|
|
||||||
|
|
||||||
if let Some(def) = <Self as PyMappingReversedProtocolImpl>::__reversed__() {
|
|
||||||
methods.push(def)
|
|
||||||
}
|
|
||||||
|
|
||||||
methods
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trait PyMappingLenProtocolImpl {
|
trait PyMappingLenProtocolImpl {
|
||||||
|
@ -242,17 +226,3 @@ where
|
||||||
<T as DelSetItemDispatch>::det_set_dispatch()
|
<T as DelSetItemDispatch>::det_set_dispatch()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub trait PyMappingReversedProtocolImpl {
|
|
||||||
fn __reversed__() -> Option<PyMethodDef>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'p, T> PyMappingReversedProtocolImpl for T
|
|
||||||
where
|
|
||||||
T: PyMappingProtocol<'p>,
|
|
||||||
{
|
|
||||||
default fn __reversed__() -> Option<PyMethodDef> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -135,16 +135,16 @@ impl PySetterDef {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Implementation detail. Only to be used through the proc macros.
|
/// Implementation detail. Only to be used through the proc macros.
|
||||||
/// Allows arbitrary pymethod blocks to submit their methods, which are eventually
|
/// Allows arbitrary `#[pymethod]/#[pyproto]` blocks to submit their methods,
|
||||||
/// collected by pyclass.
|
/// which are eventually collected by `#[pyclass]`.
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[cfg(feature = "macros")]
|
#[cfg(feature = "macros")]
|
||||||
pub trait PyMethodsInventory: inventory::Collect {
|
pub trait PyMethodsInventory: inventory::Collect {
|
||||||
/// Create a new instance
|
/// Create a new instance
|
||||||
fn new(methods: &'static [PyMethodDefType]) -> Self;
|
fn new(methods: &'static [PyMethodDefType]) -> Self;
|
||||||
|
|
||||||
/// Returns the methods for a single impl block
|
/// Returns the methods for a single `#[pymethods] impl` block
|
||||||
fn get_methods(&self) -> &'static [PyMethodDefType];
|
fn get(&self) -> &'static [PyMethodDefType];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Implementation detail. Only to be used through the proc macros.
|
/// Implementation detail. Only to be used through the proc macros.
|
||||||
|
@ -159,7 +159,7 @@ pub trait PyMethodsImpl {
|
||||||
fn py_methods() -> Vec<&'static PyMethodDefType> {
|
fn py_methods() -> Vec<&'static PyMethodDefType> {
|
||||||
inventory::iter::<Self::Methods>
|
inventory::iter::<Self::Methods>
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flat_map(PyMethodsInventory::get_methods)
|
.flat_map(PyMethodsInventory::get)
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
//! Trait and support implementation for implementing number protocol
|
//! Trait and support implementation for implementing number protocol
|
||||||
|
|
||||||
use crate::class::basic::PyObjectProtocolImpl;
|
use crate::class::basic::PyObjectProtocolImpl;
|
||||||
use crate::class::methods::PyMethodDef;
|
|
||||||
use crate::err::PyResult;
|
use crate::err::PyResult;
|
||||||
use crate::{ffi, FromPyObject, IntoPy, PyClass, PyObject};
|
use crate::{ffi, FromPyObject, IntoPy, PyClass, PyObject};
|
||||||
|
|
||||||
|
@ -619,14 +618,10 @@ pub trait PyNumberIndexProtocol<'p>: PyNumberProtocol<'p> {
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub trait PyNumberProtocolImpl: PyObjectProtocolImpl {
|
pub trait PyNumberProtocolImpl: PyObjectProtocolImpl {
|
||||||
fn methods() -> Vec<PyMethodDef>;
|
|
||||||
fn tp_as_number() -> Option<ffi::PyNumberMethods>;
|
fn tp_as_number() -> Option<ffi::PyNumberMethods>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'p, T> PyNumberProtocolImpl for T {
|
impl<'p, T> PyNumberProtocolImpl for T {
|
||||||
default fn methods() -> Vec<PyMethodDef> {
|
|
||||||
Vec::new()
|
|
||||||
}
|
|
||||||
default fn tp_as_number() -> Option<ffi::PyNumberMethods> {
|
default fn tp_as_number() -> Option<ffi::PyNumberMethods> {
|
||||||
if let Some(nb_bool) = <Self as PyObjectProtocolImpl>::nb_bool_fn() {
|
if let Some(nb_bool) = <Self as PyObjectProtocolImpl>::nb_bool_fn() {
|
||||||
let meth = ffi::PyNumberMethods {
|
let meth = ffi::PyNumberMethods {
|
||||||
|
@ -684,62 +679,6 @@ where
|
||||||
nb_inplace_matrix_multiply: Self::nb_inplace_matrix_multiply(),
|
nb_inplace_matrix_multiply: Self::nb_inplace_matrix_multiply(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn methods() -> Vec<PyMethodDef> {
|
|
||||||
let mut methods = Vec::new();
|
|
||||||
|
|
||||||
if let Some(def) = <Self as PyNumberRAddProtocolImpl>::__radd__() {
|
|
||||||
methods.push(def)
|
|
||||||
}
|
|
||||||
if let Some(def) = <Self as PyNumberRSubProtocolImpl>::__rsub__() {
|
|
||||||
methods.push(def)
|
|
||||||
}
|
|
||||||
if let Some(def) = <Self as PyNumberRMulProtocolImpl>::__rmul__() {
|
|
||||||
methods.push(def)
|
|
||||||
}
|
|
||||||
if let Some(def) = <Self as PyNumberRMatmulProtocolImpl>::__rmatmul__() {
|
|
||||||
methods.push(def)
|
|
||||||
}
|
|
||||||
if let Some(def) = <Self as PyNumberRTruedivProtocolImpl>::__rtruediv__() {
|
|
||||||
methods.push(def)
|
|
||||||
}
|
|
||||||
if let Some(def) = <Self as PyNumberRFloordivProtocolImpl>::__rfloordiv__() {
|
|
||||||
methods.push(def)
|
|
||||||
}
|
|
||||||
if let Some(def) = <Self as PyNumberRModProtocolImpl>::__rmod__() {
|
|
||||||
methods.push(def)
|
|
||||||
}
|
|
||||||
if let Some(def) = <Self as PyNumberRDivmodProtocolImpl>::__rdivmod__() {
|
|
||||||
methods.push(def)
|
|
||||||
}
|
|
||||||
if let Some(def) = <Self as PyNumberRPowProtocolImpl>::__rpow__() {
|
|
||||||
methods.push(def)
|
|
||||||
}
|
|
||||||
if let Some(def) = <Self as PyNumberRLShiftProtocolImpl>::__rlshift__() {
|
|
||||||
methods.push(def)
|
|
||||||
}
|
|
||||||
if let Some(def) = <Self as PyNumberRRShiftProtocolImpl>::__rrshift__() {
|
|
||||||
methods.push(def)
|
|
||||||
}
|
|
||||||
if let Some(def) = <Self as PyNumberRAndProtocolImpl>::__rand__() {
|
|
||||||
methods.push(def)
|
|
||||||
}
|
|
||||||
if let Some(def) = <Self as PyNumberRXorProtocolImpl>::__rxor__() {
|
|
||||||
methods.push(def)
|
|
||||||
}
|
|
||||||
if let Some(def) = <Self as PyNumberROrProtocolImpl>::__ror__() {
|
|
||||||
methods.push(def)
|
|
||||||
}
|
|
||||||
if let Some(def) = <Self as PyNumberComplexProtocolImpl>::__complex__() {
|
|
||||||
methods.push(def)
|
|
||||||
}
|
|
||||||
if let Some(def) = <Self as PyNumberRoundProtocolImpl>::__round__() {
|
|
||||||
methods.push(def)
|
|
||||||
}
|
|
||||||
|
|
||||||
methods
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trait PyNumberAddProtocolImpl {
|
trait PyNumberAddProtocolImpl {
|
||||||
|
@ -1336,20 +1275,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub trait PyNumberRAddProtocolImpl {
|
|
||||||
fn __radd__() -> Option<PyMethodDef>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'p, T> PyNumberRAddProtocolImpl for T
|
|
||||||
where
|
|
||||||
T: PyNumberProtocol<'p>,
|
|
||||||
{
|
|
||||||
default fn __radd__() -> Option<PyMethodDef> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fallback trait for nb_add
|
// Fallback trait for nb_add
|
||||||
trait PyNumberAddFallback {
|
trait PyNumberAddFallback {
|
||||||
fn nb_add_fallback() -> Option<ffi::binaryfunc>;
|
fn nb_add_fallback() -> Option<ffi::binaryfunc>;
|
||||||
|
@ -1373,20 +1298,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub trait PyNumberRSubProtocolImpl {
|
|
||||||
fn __rsub__() -> Option<PyMethodDef>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'p, T> PyNumberRSubProtocolImpl for T
|
|
||||||
where
|
|
||||||
T: PyNumberProtocol<'p>,
|
|
||||||
{
|
|
||||||
default fn __rsub__() -> Option<PyMethodDef> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
trait PyNumberSubFallback {
|
trait PyNumberSubFallback {
|
||||||
fn nb_sub_fallback() -> Option<ffi::binaryfunc>;
|
fn nb_sub_fallback() -> Option<ffi::binaryfunc>;
|
||||||
}
|
}
|
||||||
|
@ -1409,20 +1320,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub trait PyNumberRMulProtocolImpl {
|
|
||||||
fn __rmul__() -> Option<PyMethodDef>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'p, T> PyNumberRMulProtocolImpl for T
|
|
||||||
where
|
|
||||||
T: PyNumberProtocol<'p>,
|
|
||||||
{
|
|
||||||
default fn __rmul__() -> Option<PyMethodDef> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
trait PyNumberMulFallback {
|
trait PyNumberMulFallback {
|
||||||
fn nb_mul_fallback() -> Option<ffi::binaryfunc>;
|
fn nb_mul_fallback() -> Option<ffi::binaryfunc>;
|
||||||
}
|
}
|
||||||
|
@ -1445,20 +1342,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub trait PyNumberRMatmulProtocolImpl {
|
|
||||||
fn __rmatmul__() -> Option<PyMethodDef>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'p, T> PyNumberRMatmulProtocolImpl for T
|
|
||||||
where
|
|
||||||
T: PyNumberProtocol<'p>,
|
|
||||||
{
|
|
||||||
default fn __rmatmul__() -> Option<PyMethodDef> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
trait PyNumberMatmulFallback {
|
trait PyNumberMatmulFallback {
|
||||||
fn nb_matmul_fallback() -> Option<ffi::binaryfunc>;
|
fn nb_matmul_fallback() -> Option<ffi::binaryfunc>;
|
||||||
}
|
}
|
||||||
|
@ -1481,20 +1364,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub trait PyNumberRTruedivProtocolImpl {
|
|
||||||
fn __rtruediv__() -> Option<PyMethodDef>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'p, T> PyNumberRTruedivProtocolImpl for T
|
|
||||||
where
|
|
||||||
T: PyNumberProtocol<'p>,
|
|
||||||
{
|
|
||||||
default fn __rtruediv__() -> Option<PyMethodDef> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
trait PyNumberTruedivFallback {
|
trait PyNumberTruedivFallback {
|
||||||
fn nb_truediv_fallback() -> Option<ffi::binaryfunc>;
|
fn nb_truediv_fallback() -> Option<ffi::binaryfunc>;
|
||||||
}
|
}
|
||||||
|
@ -1517,20 +1386,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub trait PyNumberRFloordivProtocolImpl {
|
|
||||||
fn __rfloordiv__() -> Option<PyMethodDef>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'p, T> PyNumberRFloordivProtocolImpl for T
|
|
||||||
where
|
|
||||||
T: PyNumberProtocol<'p>,
|
|
||||||
{
|
|
||||||
default fn __rfloordiv__() -> Option<PyMethodDef> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
trait PyNumberFloordivFallback {
|
trait PyNumberFloordivFallback {
|
||||||
fn nb_floordiv_fallback() -> Option<ffi::binaryfunc>;
|
fn nb_floordiv_fallback() -> Option<ffi::binaryfunc>;
|
||||||
}
|
}
|
||||||
|
@ -1553,20 +1408,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub trait PyNumberRModProtocolImpl {
|
|
||||||
fn __rmod__() -> Option<PyMethodDef>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'p, T> PyNumberRModProtocolImpl for T
|
|
||||||
where
|
|
||||||
T: PyNumberProtocol<'p>,
|
|
||||||
{
|
|
||||||
default fn __rmod__() -> Option<PyMethodDef> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
trait PyNumberModFallback {
|
trait PyNumberModFallback {
|
||||||
fn nb_mod_fallback() -> Option<ffi::binaryfunc>;
|
fn nb_mod_fallback() -> Option<ffi::binaryfunc>;
|
||||||
}
|
}
|
||||||
|
@ -1589,20 +1430,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub trait PyNumberRDivmodProtocolImpl {
|
|
||||||
fn __rdivmod__() -> Option<PyMethodDef>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'p, T> PyNumberRDivmodProtocolImpl for T
|
|
||||||
where
|
|
||||||
T: PyNumberProtocol<'p>,
|
|
||||||
{
|
|
||||||
default fn __rdivmod__() -> Option<PyMethodDef> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
trait PyNumberDivmodFallback {
|
trait PyNumberDivmodFallback {
|
||||||
fn nb_divmod_fallback() -> Option<ffi::binaryfunc>;
|
fn nb_divmod_fallback() -> Option<ffi::binaryfunc>;
|
||||||
}
|
}
|
||||||
|
@ -1625,20 +1452,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub trait PyNumberRPowProtocolImpl {
|
|
||||||
fn __rpow__() -> Option<PyMethodDef>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'p, T> PyNumberRPowProtocolImpl for T
|
|
||||||
where
|
|
||||||
T: PyNumberProtocol<'p>,
|
|
||||||
{
|
|
||||||
default fn __rpow__() -> Option<PyMethodDef> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
trait PyNumberPowFallback {
|
trait PyNumberPowFallback {
|
||||||
fn nb_pow_fallback() -> Option<ffi::ternaryfunc>;
|
fn nb_pow_fallback() -> Option<ffi::ternaryfunc>;
|
||||||
}
|
}
|
||||||
|
@ -1661,20 +1474,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub trait PyNumberRLShiftProtocolImpl {
|
|
||||||
fn __rlshift__() -> Option<PyMethodDef>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'p, T> PyNumberRLShiftProtocolImpl for T
|
|
||||||
where
|
|
||||||
T: PyNumberProtocol<'p>,
|
|
||||||
{
|
|
||||||
default fn __rlshift__() -> Option<PyMethodDef> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
trait PyNumberLShiftFallback {
|
trait PyNumberLShiftFallback {
|
||||||
fn nb_lshift_fallback() -> Option<ffi::binaryfunc>;
|
fn nb_lshift_fallback() -> Option<ffi::binaryfunc>;
|
||||||
}
|
}
|
||||||
|
@ -1697,20 +1496,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub trait PyNumberRRShiftProtocolImpl {
|
|
||||||
fn __rrshift__() -> Option<PyMethodDef>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'p, T> PyNumberRRShiftProtocolImpl for T
|
|
||||||
where
|
|
||||||
T: PyNumberProtocol<'p>,
|
|
||||||
{
|
|
||||||
default fn __rrshift__() -> Option<PyMethodDef> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
trait PyNumberRRshiftFallback {
|
trait PyNumberRRshiftFallback {
|
||||||
fn nb_rshift_fallback() -> Option<ffi::binaryfunc>;
|
fn nb_rshift_fallback() -> Option<ffi::binaryfunc>;
|
||||||
}
|
}
|
||||||
|
@ -1733,20 +1518,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub trait PyNumberRAndProtocolImpl {
|
|
||||||
fn __rand__() -> Option<PyMethodDef>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'p, T> PyNumberRAndProtocolImpl for T
|
|
||||||
where
|
|
||||||
T: PyNumberProtocol<'p>,
|
|
||||||
{
|
|
||||||
default fn __rand__() -> Option<PyMethodDef> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
trait PyNumberAndFallback {
|
trait PyNumberAndFallback {
|
||||||
fn nb_and_fallback() -> Option<ffi::binaryfunc>;
|
fn nb_and_fallback() -> Option<ffi::binaryfunc>;
|
||||||
}
|
}
|
||||||
|
@ -1769,20 +1540,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub trait PyNumberRXorProtocolImpl {
|
|
||||||
fn __rxor__() -> Option<PyMethodDef>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'p, T> PyNumberRXorProtocolImpl for T
|
|
||||||
where
|
|
||||||
T: PyNumberProtocol<'p>,
|
|
||||||
{
|
|
||||||
default fn __rxor__() -> Option<PyMethodDef> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
trait PyNumberXorFallback {
|
trait PyNumberXorFallback {
|
||||||
fn nb_xor_fallback() -> Option<ffi::binaryfunc>;
|
fn nb_xor_fallback() -> Option<ffi::binaryfunc>;
|
||||||
}
|
}
|
||||||
|
@ -1805,20 +1562,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub trait PyNumberROrProtocolImpl {
|
|
||||||
fn __ror__() -> Option<PyMethodDef>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'p, T> PyNumberROrProtocolImpl for T
|
|
||||||
where
|
|
||||||
T: PyNumberProtocol<'p>,
|
|
||||||
{
|
|
||||||
default fn __ror__() -> Option<PyMethodDef> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
trait PyNumberOrFallback {
|
trait PyNumberOrFallback {
|
||||||
fn nb_or_fallback() -> Option<ffi::binaryfunc>;
|
fn nb_or_fallback() -> Option<ffi::binaryfunc>;
|
||||||
}
|
}
|
||||||
|
@ -1995,29 +1738,3 @@ where
|
||||||
py_unary_func!(PyNumberIndexProtocol, T::__index__)
|
py_unary_func!(PyNumberIndexProtocol, T::__index__)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait PyNumberComplexProtocolImpl {
|
|
||||||
fn __complex__() -> Option<PyMethodDef>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'p, T> PyNumberComplexProtocolImpl for T
|
|
||||||
where
|
|
||||||
T: PyNumberProtocol<'p>,
|
|
||||||
{
|
|
||||||
default fn __complex__() -> Option<PyMethodDef> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait PyNumberRoundProtocolImpl {
|
|
||||||
fn __round__() -> Option<PyMethodDef>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'p, T> PyNumberRoundProtocolImpl for T
|
|
||||||
where
|
|
||||||
T: PyNumberProtocol<'p>,
|
|
||||||
{
|
|
||||||
default fn __round__() -> Option<PyMethodDef> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
//! [PEP-0492](https://www.python.org/dev/peps/pep-0492/)
|
//! [PEP-0492](https://www.python.org/dev/peps/pep-0492/)
|
||||||
//!
|
//!
|
||||||
|
|
||||||
use crate::class::methods::PyMethodDef;
|
|
||||||
use crate::err::PyResult;
|
use crate::err::PyResult;
|
||||||
use crate::{ffi, PyClass, PyObject};
|
use crate::{ffi, PyClass, PyObject};
|
||||||
|
|
||||||
|
@ -89,17 +88,12 @@ pub trait PyAsyncAexitProtocol<'p>: PyAsyncProtocol<'p> {
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub trait PyAsyncProtocolImpl {
|
pub trait PyAsyncProtocolImpl {
|
||||||
fn tp_as_async() -> Option<ffi::PyAsyncMethods>;
|
fn tp_as_async() -> Option<ffi::PyAsyncMethods>;
|
||||||
fn methods() -> Vec<PyMethodDef>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> PyAsyncProtocolImpl for T {
|
impl<T> PyAsyncProtocolImpl for T {
|
||||||
default fn tp_as_async() -> Option<ffi::PyAsyncMethods> {
|
default fn tp_as_async() -> Option<ffi::PyAsyncMethods> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
default fn methods() -> Vec<PyMethodDef> {
|
|
||||||
Vec::new()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'p, T> PyAsyncProtocolImpl for T
|
impl<'p, T> PyAsyncProtocolImpl for T
|
||||||
|
@ -114,20 +108,6 @@ where
|
||||||
am_anext: Self::am_anext(),
|
am_anext: Self::am_anext(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn methods() -> Vec<PyMethodDef> {
|
|
||||||
let mut methods = Vec::new();
|
|
||||||
|
|
||||||
if let Some(def) = <Self as PyAsyncAenterProtocolImpl>::__aenter__() {
|
|
||||||
methods.push(def)
|
|
||||||
}
|
|
||||||
if let Some(def) = <Self as PyAsyncAexitProtocolImpl>::__aexit__() {
|
|
||||||
methods.push(def)
|
|
||||||
}
|
|
||||||
|
|
||||||
methods
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trait PyAsyncAwaitProtocolImpl {
|
trait PyAsyncAwaitProtocolImpl {
|
||||||
|
@ -227,29 +207,3 @@ mod anext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trait PyAsyncAenterProtocolImpl {
|
|
||||||
fn __aenter__() -> Option<PyMethodDef>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'p, T> PyAsyncAenterProtocolImpl for T
|
|
||||||
where
|
|
||||||
T: PyAsyncProtocol<'p>,
|
|
||||||
{
|
|
||||||
default fn __aenter__() -> Option<PyMethodDef> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
trait PyAsyncAexitProtocolImpl {
|
|
||||||
fn __aexit__() -> Option<PyMethodDef>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'p, T> PyAsyncAexitProtocolImpl for T
|
|
||||||
where
|
|
||||||
T: PyAsyncProtocol<'p>,
|
|
||||||
{
|
|
||||||
default fn __aexit__() -> Option<PyMethodDef> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -172,7 +172,7 @@ where
|
||||||
// normal methods
|
// normal methods
|
||||||
if !methods.is_empty() {
|
if !methods.is_empty() {
|
||||||
methods.push(ffi::PyMethodDef_INIT);
|
methods.push(ffi::PyMethodDef_INIT);
|
||||||
type_object.tp_methods = Box::into_raw(methods.into_boxed_slice()) as *mut _;
|
type_object.tp_methods = Box::into_raw(methods.into_boxed_slice()) as _;
|
||||||
}
|
}
|
||||||
|
|
||||||
// class attributes
|
// class attributes
|
||||||
|
@ -197,7 +197,7 @@ where
|
||||||
}
|
}
|
||||||
if !props.is_empty() {
|
if !props.is_empty() {
|
||||||
props.push(ffi::PyGetSetDef_INIT);
|
props.push(ffi::PyGetSetDef_INIT);
|
||||||
type_object.tp_getset = Box::into_raw(props.into_boxed_slice()) as *mut _;
|
type_object.tp_getset = Box::into_raw(props.into_boxed_slice()) as _;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set type flags
|
// set type flags
|
||||||
|
@ -264,33 +264,9 @@ fn py_class_method_defs<T: PyMethodsImpl>() -> (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for def in <T as class::basic::PyObjectProtocolImpl>::methods() {
|
|
||||||
defs.push(def.as_method_def());
|
|
||||||
}
|
|
||||||
for def in <T as class::context::PyContextProtocolImpl>::methods() {
|
|
||||||
defs.push(def.as_method_def());
|
|
||||||
}
|
|
||||||
for def in <T as class::mapping::PyMappingProtocolImpl>::methods() {
|
|
||||||
defs.push(def.as_method_def());
|
|
||||||
}
|
|
||||||
for def in <T as class::number::PyNumberProtocolImpl>::methods() {
|
|
||||||
defs.push(def.as_method_def());
|
|
||||||
}
|
|
||||||
for def in <T as class::descr::PyDescrProtocolImpl>::methods() {
|
|
||||||
defs.push(def.as_method_def());
|
|
||||||
}
|
|
||||||
|
|
||||||
py_class_async_methods::<T>(&mut defs);
|
|
||||||
|
|
||||||
(new, call, defs, attrs)
|
(new, call, defs, attrs)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn py_class_async_methods<T>(defs: &mut Vec<ffi::PyMethodDef>) {
|
|
||||||
for def in <T as class::pyasync::PyAsyncProtocolImpl>::methods() {
|
|
||||||
defs.push(def.as_method_def());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn py_class_properties<T: PyMethodsImpl>() -> Vec<ffi::PyGetSetDef> {
|
fn py_class_properties<T: PyMethodsImpl>() -> Vec<ffi::PyGetSetDef> {
|
||||||
let mut defs = std::collections::HashMap::new();
|
let mut defs = std::collections::HashMap::new();
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
#![feature(specialization)]
|
|
||||||
|
|
||||||
use pyo3::class::basic::CompareOp;
|
use pyo3::class::basic::CompareOp;
|
||||||
use pyo3::class::*;
|
use pyo3::class::*;
|
||||||
use pyo3::prelude::*;
|
use pyo3::prelude::*;
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
#![feature(specialization)]
|
|
||||||
|
|
||||||
use pyo3::class::{
|
use pyo3::class::{
|
||||||
PyContextProtocol, PyIterProtocol, PyMappingProtocol, PyObjectProtocol, PySequenceProtocol,
|
PyContextProtocol, PyIterProtocol, PyMappingProtocol, PyObjectProtocol, PySequenceProtocol,
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#![feature(specialization)]
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use pyo3::exceptions::KeyError;
|
use pyo3::exceptions::KeyError;
|
||||||
|
|
Loading…
Reference in a new issue