Merge pull request #1328 from davidhewitt/pyproto-no-inventory
pyproto: remove inventory from implementation
This commit is contained in:
commit
33b3da3337
|
@ -772,23 +772,31 @@ impl pyo3::class::methods::HasMethodsInventory for MyClass {
|
||||||
}
|
}
|
||||||
pyo3::inventory::collect!(Pyo3MethodsInventoryForMyClass);
|
pyo3::inventory::collect!(Pyo3MethodsInventoryForMyClass);
|
||||||
|
|
||||||
|
impl pyo3::class::proto_methods::PyProtoMethods for MyClass {
|
||||||
pub struct Pyo3ProtoInventoryForMyClass {
|
fn for_each_proto_slot<Visitor: FnMut(pyo3::ffi::PyType_Slot)>(visitor: Visitor) {
|
||||||
def: pyo3::class::proto_methods::PyProtoMethodDef,
|
// Implementation which uses dtolnay specialization to load all slots.
|
||||||
}
|
use pyo3::class::proto_methods::*;
|
||||||
impl pyo3::class::proto_methods::PyProtoInventory for Pyo3ProtoInventoryForMyClass {
|
let protocols = PyClassProtocols::<MyClass>::new();
|
||||||
fn new(def: pyo3::class::proto_methods::PyProtoMethodDef) -> Self {
|
protocols.object_protocol_slots()
|
||||||
Self { def }
|
.iter()
|
||||||
|
.chain(protocols.number_protocol_slots())
|
||||||
|
.chain(protocols.iter_protocol_slots())
|
||||||
|
.chain(protocols.gc_protocol_slots())
|
||||||
|
.chain(protocols.descr_protocol_slots())
|
||||||
|
.chain(protocols.mapping_protocol_slots())
|
||||||
|
.chain(protocols.sequence_protocol_slots())
|
||||||
|
.chain(protocols.async_protocol_slots())
|
||||||
|
.chain(protocols.buffer_protocol_slots())
|
||||||
|
.cloned()
|
||||||
|
.for_each(visitor);
|
||||||
}
|
}
|
||||||
fn get(&'static self) -> &'static pyo3::class::proto_methods::PyProtoMethodDef {
|
|
||||||
&self.def
|
fn get_buffer() -> Option<&'static pyo3::class::proto_methods::PyBufferProcs> {
|
||||||
|
use pyo3::class::proto_methods::*;
|
||||||
|
let protocols = PyClassProtocols::<MyClass>::new();
|
||||||
|
protocols.buffer_procs()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl pyo3::class::proto_methods::HasProtoInventory for MyClass {
|
|
||||||
type ProtoMethods = Pyo3ProtoInventoryForMyClass;
|
|
||||||
}
|
|
||||||
pyo3::inventory::collect!(Pyo3ProtoInventoryForMyClass);
|
|
||||||
|
|
||||||
|
|
||||||
impl pyo3::pyclass::PyClassSend for MyClass {
|
impl pyo3::pyclass::PyClassSend for MyClass {
|
||||||
type ThreadChecker = pyo3::pyclass::ThreadCheckerStub<MyClass>;
|
type ThreadChecker = pyo3::pyclass::ThreadCheckerStub<MyClass>;
|
||||||
|
|
|
@ -6,14 +6,18 @@ use std::collections::HashSet;
|
||||||
pub struct Proto {
|
pub struct Proto {
|
||||||
/// The name of this protocol. E.g., Iter.
|
/// The name of this protocol. E.g., Iter.
|
||||||
pub name: &'static str,
|
pub name: &'static str,
|
||||||
/// Extension trait that has `get_*` methods
|
/// The path to the module which contains this proto implementation.
|
||||||
pub extension_trait: &'static str,
|
module: &'static str,
|
||||||
|
/// Trait which stores the slots
|
||||||
|
pub slots_trait: &'static str,
|
||||||
|
/// Trait method which accesses the slots.
|
||||||
|
pub slots_trait_slots: &'static str,
|
||||||
/// All methods.
|
/// All methods.
|
||||||
pub methods: &'static [MethodProto],
|
pub methods: &'static [MethodProto],
|
||||||
/// All methods registered as normal methods like `#[pymethods]`.
|
/// All methods registered as normal methods like `#[pymethods]`.
|
||||||
pub py_methods: &'static [PyMethod],
|
pub py_methods: &'static [PyMethod],
|
||||||
/// All methods registered to the slot table.
|
/// All methods registered to the slot table.
|
||||||
slot_getters: &'static [SlotGetter],
|
slot_defs: &'static [SlotDef],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Proto {
|
impl Proto {
|
||||||
|
@ -23,32 +27,41 @@ impl Proto {
|
||||||
{
|
{
|
||||||
self.methods.iter().find(|m| query == m.name)
|
self.methods.iter().find(|m| query == m.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_method<Q>(&self, query: Q) -> Option<&'static PyMethod>
|
pub(crate) fn get_method<Q>(&self, query: Q) -> Option<&'static PyMethod>
|
||||||
where
|
where
|
||||||
Q: PartialEq<&'static str>,
|
Q: PartialEq<&'static str>,
|
||||||
{
|
{
|
||||||
self.py_methods.iter().find(|m| query == m.name)
|
self.py_methods.iter().find(|m| query == m.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the hard-coded module as a path
|
||||||
|
#[inline]
|
||||||
|
pub(crate) fn module(&self) -> syn::Path {
|
||||||
|
syn::parse_str(self.module).expect("module def not valid path")
|
||||||
|
}
|
||||||
|
|
||||||
// Since the order matters, we expose only the iterator instead of the slice.
|
// Since the order matters, we expose only the iterator instead of the slice.
|
||||||
pub(crate) fn slot_getters(
|
pub(crate) fn slot_defs(
|
||||||
&self,
|
&self,
|
||||||
mut implemented_protocols: HashSet<String>,
|
mut implemented_protocols: HashSet<String>,
|
||||||
) -> impl Iterator<Item = &'static str> {
|
) -> impl Iterator<Item = &'static SlotDef> {
|
||||||
self.slot_getters.iter().filter_map(move |getter| {
|
self.slot_defs.iter().filter(move |slot_def| {
|
||||||
// If any required method is not implemented, we skip this setter.
|
// If any required method is not implemented, we skip this def.
|
||||||
if getter
|
let all_methods_implemented = slot_def
|
||||||
.proto_names
|
.proto_names
|
||||||
.iter()
|
.iter()
|
||||||
.any(|name| !implemented_protocols.contains(*name))
|
.all(|name| implemented_protocols.contains(*name));
|
||||||
{
|
|
||||||
return None;
|
if all_methods_implemented {
|
||||||
}
|
// To use 'paired' def in priority, we remove used protocols.
|
||||||
// To use 'paired' setter in priority, we remove used protocols.
|
// For example, if add_radd is already used, we shouldn't use add and radd.
|
||||||
// For example, if set_add_radd is already used, we shouldn't use set_add and set_radd.
|
for name in slot_def.proto_names {
|
||||||
for name in getter.proto_names {
|
|
||||||
implemented_protocols.remove(*name);
|
implemented_protocols.remove(*name);
|
||||||
}
|
}
|
||||||
Some(getter.get_function)
|
}
|
||||||
|
|
||||||
|
all_methods_implemented
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,584 +92,517 @@ impl PyMethod {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents a setter used to register a method to the method table.
|
/// Represents a slot definition.
|
||||||
struct SlotGetter {
|
pub struct SlotDef {
|
||||||
/// Protocols necessary for invoking this setter.
|
/// Protocols necessary to meet this def.
|
||||||
/// E.g., we need `__setattr__` and `__delattr__` for invoking `set_setdelitem`.
|
/// E.g., we need `__setattr__` and `__delattr__` for invoking `set_setdelitem`.
|
||||||
pub proto_names: &'static [&'static str],
|
pub proto_names: &'static [&'static str],
|
||||||
/// The name of the setter called to the method table.
|
/// The Python slot name.
|
||||||
pub get_function: &'static str,
|
pub slot: &'static str,
|
||||||
|
/// The name of the function in pyo3 which implements the slot.
|
||||||
|
pub slot_impl: &'static str,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SlotGetter {
|
impl SlotDef {
|
||||||
const fn new(names: &'static [&'static str], get_function: &'static str) -> Self {
|
const fn new(
|
||||||
SlotGetter {
|
proto_names: &'static [&'static str],
|
||||||
proto_names: names,
|
slot: &'static str,
|
||||||
get_function,
|
slot_impl: &'static str,
|
||||||
|
) -> Self {
|
||||||
|
SlotDef {
|
||||||
|
proto_names,
|
||||||
|
slot,
|
||||||
|
slot_impl,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const OBJECT: Proto = Proto {
|
pub const OBJECT: Proto = Proto {
|
||||||
name: "Object",
|
name: "Object",
|
||||||
extension_trait: "pyo3::class::basic::PyBasicSlots",
|
module: "pyo3::class::basic",
|
||||||
|
slots_trait: "PyObjectProtocolSlots",
|
||||||
|
slots_trait_slots: "object_protocol_slots",
|
||||||
methods: &[
|
methods: &[
|
||||||
MethodProto::new("__getattr__", "pyo3::class::basic::PyObjectGetAttrProtocol")
|
MethodProto::new("__getattr__", "PyObjectGetAttrProtocol")
|
||||||
.args(&["Name"])
|
.args(&["Name"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new("__setattr__", "pyo3::class::basic::PyObjectSetAttrProtocol")
|
MethodProto::new("__setattr__", "PyObjectSetAttrProtocol")
|
||||||
.args(&["Name", "Value"])
|
.args(&["Name", "Value"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new("__delattr__", "pyo3::class::basic::PyObjectDelAttrProtocol")
|
MethodProto::new("__delattr__", "PyObjectDelAttrProtocol")
|
||||||
.args(&["Name"])
|
.args(&["Name"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new("__str__", "pyo3::class::basic::PyObjectStrProtocol").has_self(),
|
MethodProto::new("__str__", "PyObjectStrProtocol").has_self(),
|
||||||
MethodProto::new("__repr__", "pyo3::class::basic::PyObjectReprProtocol").has_self(),
|
MethodProto::new("__repr__", "PyObjectReprProtocol").has_self(),
|
||||||
MethodProto::new("__format__", "pyo3::class::basic::PyObjectFormatProtocol")
|
MethodProto::new("__format__", "PyObjectFormatProtocol")
|
||||||
.args(&["Format"])
|
.args(&["Format"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new("__hash__", "pyo3::class::basic::PyObjectHashProtocol").has_self(),
|
MethodProto::new("__hash__", "PyObjectHashProtocol").has_self(),
|
||||||
MethodProto::new("__bytes__", "pyo3::class::basic::PyObjectBytesProtocol").has_self(),
|
MethodProto::new("__bytes__", "PyObjectBytesProtocol").has_self(),
|
||||||
MethodProto::new("__richcmp__", "pyo3::class::basic::PyObjectRichcmpProtocol")
|
MethodProto::new("__richcmp__", "PyObjectRichcmpProtocol")
|
||||||
.args(&["Other"])
|
.args(&["Other"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new("__bool__", "pyo3::class::basic::PyObjectBoolProtocol").has_self(),
|
MethodProto::new("__bool__", "PyObjectBoolProtocol").has_self(),
|
||||||
],
|
],
|
||||||
py_methods: &[
|
py_methods: &[
|
||||||
PyMethod::new("__format__", "pyo3::class::basic::FormatProtocolImpl"),
|
PyMethod::new("__format__", "FormatProtocolImpl"),
|
||||||
PyMethod::new("__bytes__", "pyo3::class::basic::BytesProtocolImpl"),
|
PyMethod::new("__bytes__", "BytesProtocolImpl"),
|
||||||
PyMethod::new("__unicode__", "pyo3::class::basic::UnicodeProtocolImpl"),
|
PyMethod::new("__unicode__", "UnicodeProtocolImpl"),
|
||||||
],
|
],
|
||||||
slot_getters: &[
|
slot_defs: &[
|
||||||
SlotGetter::new(&["__str__"], "get_str"),
|
SlotDef::new(&["__str__"], "Py_tp_str", "str"),
|
||||||
SlotGetter::new(&["__repr__"], "get_repr"),
|
SlotDef::new(&["__repr__"], "Py_tp_repr", "repr"),
|
||||||
SlotGetter::new(&["__hash__"], "get_hash"),
|
SlotDef::new(&["__hash__"], "Py_tp_hash", "hash"),
|
||||||
SlotGetter::new(&["__getattr__"], "get_getattr"),
|
SlotDef::new(&["__getattr__"], "Py_tp_getattro", "getattr"),
|
||||||
SlotGetter::new(&["__richcmp__"], "get_richcmp"),
|
SlotDef::new(&["__richcmp__"], "Py_tp_richcompare", "richcmp"),
|
||||||
SlotGetter::new(&["__setattr__", "__delattr__"], "get_setdelattr"),
|
SlotDef::new(
|
||||||
SlotGetter::new(&["__setattr__"], "get_setattr"),
|
&["__setattr__", "__delattr__"],
|
||||||
SlotGetter::new(&["__delattr__"], "get_delattr"),
|
"Py_tp_setattro",
|
||||||
SlotGetter::new(&["__bool__"], "get_bool"),
|
"setdelattr",
|
||||||
|
),
|
||||||
|
SlotDef::new(&["__setattr__"], "Py_tp_setattro", "setattr"),
|
||||||
|
SlotDef::new(&["__delattr__"], "Py_tp_setattro", "delattr"),
|
||||||
|
SlotDef::new(&["__bool__"], "Py_nb_bool", "bool"),
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const ASYNC: Proto = Proto {
|
pub const ASYNC: Proto = Proto {
|
||||||
name: "Async",
|
name: "Async",
|
||||||
extension_trait: "pyo3::class::pyasync::PyAsyncSlots",
|
module: "pyo3::class::pyasync",
|
||||||
|
slots_trait: "PyAsyncProtocolSlots",
|
||||||
|
slots_trait_slots: "async_protocol_slots",
|
||||||
methods: &[
|
methods: &[
|
||||||
MethodProto::new("__await__", "pyo3::class::pyasync::PyAsyncAwaitProtocol")
|
MethodProto::new("__await__", "PyAsyncAwaitProtocol").args(&["Receiver"]),
|
||||||
.args(&["Receiver"]),
|
MethodProto::new("__aiter__", "PyAsyncAiterProtocol").args(&["Receiver"]),
|
||||||
MethodProto::new("__aiter__", "pyo3::class::pyasync::PyAsyncAiterProtocol")
|
MethodProto::new("__anext__", "PyAsyncAnextProtocol").args(&["Receiver"]),
|
||||||
.args(&["Receiver"]),
|
MethodProto::new("__aenter__", "PyAsyncAenterProtocol").has_self(),
|
||||||
MethodProto::new("__anext__", "pyo3::class::pyasync::PyAsyncAnextProtocol")
|
MethodProto::new("__aexit__", "PyAsyncAexitProtocol")
|
||||||
.args(&["Receiver"]),
|
|
||||||
MethodProto::new("__aenter__", "pyo3::class::pyasync::PyAsyncAenterProtocol").has_self(),
|
|
||||||
MethodProto::new("__aexit__", "pyo3::class::pyasync::PyAsyncAexitProtocol")
|
|
||||||
.args(&["ExcType", "ExcValue", "Traceback"])
|
.args(&["ExcType", "ExcValue", "Traceback"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
],
|
],
|
||||||
py_methods: &[
|
py_methods: &[
|
||||||
PyMethod::new(
|
PyMethod::new("__aenter__", "PyAsyncAenterProtocolImpl"),
|
||||||
"__aenter__",
|
PyMethod::new("__aexit__", "PyAsyncAexitProtocolImpl"),
|
||||||
"pyo3::class::pyasync::PyAsyncAenterProtocolImpl",
|
|
||||||
),
|
|
||||||
PyMethod::new(
|
|
||||||
"__aexit__",
|
|
||||||
"pyo3::class::pyasync::PyAsyncAexitProtocolImpl",
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
slot_getters: &[
|
slot_defs: &[
|
||||||
SlotGetter::new(&["__await__"], "get_await"),
|
SlotDef::new(&["__await__"], "Py_am_await", "await_"),
|
||||||
SlotGetter::new(&["__aiter__"], "get_aiter"),
|
SlotDef::new(&["__aiter__"], "Py_am_aiter", "aiter"),
|
||||||
SlotGetter::new(&["__anext__"], "get_anext"),
|
SlotDef::new(&["__anext__"], "Py_am_anext", "anext"),
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const BUFFER: Proto = Proto {
|
pub const BUFFER: Proto = Proto {
|
||||||
name: "Buffer",
|
name: "Buffer",
|
||||||
extension_trait: "pyo3::class::buffer::PyBufferSlots",
|
module: "pyo3::class::buffer",
|
||||||
|
slots_trait: "PyBufferProtocolSlots",
|
||||||
|
slots_trait_slots: "buffer_protocol_slots",
|
||||||
methods: &[
|
methods: &[
|
||||||
MethodProto::new(
|
MethodProto::new("bf_getbuffer", "PyBufferGetBufferProtocol").has_self(),
|
||||||
"bf_getbuffer",
|
MethodProto::new("bf_releasebuffer", "PyBufferReleaseBufferProtocol").has_self(),
|
||||||
"pyo3::class::buffer::PyBufferGetBufferProtocol",
|
|
||||||
)
|
|
||||||
.has_self(),
|
|
||||||
MethodProto::new(
|
|
||||||
"bf_releasebuffer",
|
|
||||||
"pyo3::class::buffer::PyBufferReleaseBufferProtocol",
|
|
||||||
)
|
|
||||||
.has_self(),
|
|
||||||
],
|
],
|
||||||
py_methods: &[],
|
py_methods: &[],
|
||||||
slot_getters: &[
|
slot_defs: &[
|
||||||
SlotGetter::new(&["bf_getbuffer"], "get_getbuffer"),
|
SlotDef::new(&["bf_getbuffer"], "Py_bf_getbuffer", "getbuffer"),
|
||||||
SlotGetter::new(&["bf_releasebuffer"], "get_releasebuffer"),
|
SlotDef::new(
|
||||||
|
&["bf_releasebuffer"],
|
||||||
|
"Py_bf_releasebuffer",
|
||||||
|
"releasebuffer",
|
||||||
|
),
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const CONTEXT: Proto = Proto {
|
pub const CONTEXT: Proto = Proto {
|
||||||
name: "Context",
|
name: "Context",
|
||||||
extension_trait: "",
|
module: "pyo3::class::context",
|
||||||
|
slots_trait: "",
|
||||||
|
slots_trait_slots: "",
|
||||||
methods: &[
|
methods: &[
|
||||||
MethodProto::new("__enter__", "pyo3::class::context::PyContextEnterProtocol").has_self(),
|
MethodProto::new("__enter__", "PyContextEnterProtocol").has_self(),
|
||||||
MethodProto::new("__exit__", "pyo3::class::context::PyContextExitProtocol")
|
MethodProto::new("__exit__", "PyContextExitProtocol")
|
||||||
.args(&["ExcType", "ExcValue", "Traceback"])
|
.args(&["ExcType", "ExcValue", "Traceback"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
],
|
],
|
||||||
py_methods: &[
|
py_methods: &[
|
||||||
PyMethod::new(
|
PyMethod::new("__enter__", "PyContextEnterProtocolImpl"),
|
||||||
"__enter__",
|
PyMethod::new("__exit__", "PyContextExitProtocolImpl"),
|
||||||
"pyo3::class::context::PyContextEnterProtocolImpl",
|
|
||||||
),
|
|
||||||
PyMethod::new(
|
|
||||||
"__exit__",
|
|
||||||
"pyo3::class::context::PyContextExitProtocolImpl",
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
slot_getters: &[],
|
slot_defs: &[],
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const GC: Proto = Proto {
|
pub const GC: Proto = Proto {
|
||||||
name: "GC",
|
name: "GC",
|
||||||
extension_trait: "pyo3::class::gc::PyGCSlots",
|
module: "pyo3::class::gc",
|
||||||
|
slots_trait: "PyGCProtocolSlots",
|
||||||
|
slots_trait_slots: "gc_protocol_slots",
|
||||||
methods: &[
|
methods: &[
|
||||||
MethodProto::new("__traverse__", "pyo3::class::gc::PyGCTraverseProtocol")
|
MethodProto::new("__traverse__", "PyGCTraverseProtocol")
|
||||||
.has_self()
|
.has_self()
|
||||||
.no_result(),
|
.no_result(),
|
||||||
MethodProto::new("__clear__", "pyo3::class::gc::PyGCClearProtocol")
|
MethodProto::new("__clear__", "PyGCClearProtocol")
|
||||||
.has_self()
|
.has_self()
|
||||||
.no_result(),
|
.no_result(),
|
||||||
],
|
],
|
||||||
py_methods: &[],
|
py_methods: &[],
|
||||||
slot_getters: &[
|
slot_defs: &[
|
||||||
SlotGetter::new(&["__traverse__"], "get_traverse"),
|
SlotDef::new(&["__traverse__"], "Py_tp_traverse", "traverse"),
|
||||||
SlotGetter::new(&["__clear__"], "get_clear"),
|
SlotDef::new(&["__clear__"], "Py_tp_clear", "clear"),
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const DESCR: Proto = Proto {
|
pub const DESCR: Proto = Proto {
|
||||||
name: "Descriptor",
|
name: "Descriptor",
|
||||||
extension_trait: "pyo3::class::descr::PyDescrSlots",
|
module: "pyo3::class::descr",
|
||||||
|
slots_trait: "PyDescrProtocolSlots",
|
||||||
|
slots_trait_slots: "descr_protocol_slots",
|
||||||
methods: &[
|
methods: &[
|
||||||
MethodProto::new("__get__", "pyo3::class::descr::PyDescrGetProtocol")
|
MethodProto::new("__get__", "PyDescrGetProtocol").args(&["Receiver", "Inst", "Owner"]),
|
||||||
.args(&["Receiver", "Inst", "Owner"]),
|
MethodProto::new("__set__", "PyDescrSetProtocol").args(&["Receiver", "Inst", "Value"]),
|
||||||
MethodProto::new("__set__", "pyo3::class::descr::PyDescrSetProtocol")
|
MethodProto::new("__det__", "PyDescrDelProtocol")
|
||||||
.args(&["Receiver", "Inst", "Value"]),
|
|
||||||
MethodProto::new("__det__", "pyo3::class::descr::PyDescrDelProtocol")
|
|
||||||
.args(&["Inst"])
|
.args(&["Inst"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new("__set_name__", "pyo3::class::descr::PyDescrSetNameProtocol")
|
MethodProto::new("__set_name__", "PyDescrSetNameProtocol")
|
||||||
.args(&["Inst"])
|
.args(&["Inst"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
],
|
],
|
||||||
py_methods: &[
|
py_methods: &[
|
||||||
PyMethod::new("__del__", "pyo3::class::context::PyDescrDelProtocolImpl"),
|
PyMethod::new("__del__", "PyDescrDelProtocolImpl"),
|
||||||
PyMethod::new(
|
PyMethod::new("__set_name__", "PyDescrNameProtocolImpl"),
|
||||||
"__set_name__",
|
|
||||||
"pyo3::class::context::PyDescrNameProtocolImpl",
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
slot_getters: &[
|
slot_defs: &[
|
||||||
SlotGetter::new(&["__get__"], "get_descr_get"),
|
SlotDef::new(&["__get__"], "Py_tp_descr_get", "descr_get"),
|
||||||
SlotGetter::new(&["__set__"], "get_descr_set"),
|
SlotDef::new(&["__set__"], "Py_tp_descr_set", "descr_set"),
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const ITER: Proto = Proto {
|
pub const ITER: Proto = Proto {
|
||||||
name: "Iter",
|
name: "Iter",
|
||||||
extension_trait: "pyo3::class::iter::PyIterSlots",
|
module: "pyo3::class::iter",
|
||||||
|
slots_trait: "PyIterProtocolSlots",
|
||||||
|
slots_trait_slots: "iter_protocol_slots",
|
||||||
py_methods: &[],
|
py_methods: &[],
|
||||||
methods: &[
|
methods: &[
|
||||||
MethodProto::new("__iter__", "pyo3::class::iter::PyIterIterProtocol").args(&["Receiver"]),
|
MethodProto::new("__iter__", "PyIterIterProtocol").args(&["Receiver"]),
|
||||||
MethodProto::new("__next__", "pyo3::class::iter::PyIterNextProtocol").args(&["Receiver"]),
|
MethodProto::new("__next__", "PyIterNextProtocol").args(&["Receiver"]),
|
||||||
],
|
],
|
||||||
slot_getters: &[
|
slot_defs: &[
|
||||||
SlotGetter::new(&["__iter__"], "get_iter"),
|
SlotDef::new(&["__iter__"], "Py_tp_iter", "iter"),
|
||||||
SlotGetter::new(&["__next__"], "get_iternext"),
|
SlotDef::new(&["__next__"], "Py_tp_iternext", "iternext"),
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const MAPPING: Proto = Proto {
|
pub const MAPPING: Proto = Proto {
|
||||||
name: "Mapping",
|
name: "Mapping",
|
||||||
extension_trait: "pyo3::class::mapping::PyMappingSlots",
|
module: "pyo3::class::mapping",
|
||||||
|
slots_trait: "PyMappingProtocolSlots",
|
||||||
|
slots_trait_slots: "mapping_protocol_slots",
|
||||||
methods: &[
|
methods: &[
|
||||||
MethodProto::new("__len__", "pyo3::class::mapping::PyMappingLenProtocol").has_self(),
|
MethodProto::new("__len__", "PyMappingLenProtocol").has_self(),
|
||||||
MethodProto::new(
|
MethodProto::new("__getitem__", "PyMappingGetItemProtocol")
|
||||||
"__getitem__",
|
|
||||||
"pyo3::class::mapping::PyMappingGetItemProtocol",
|
|
||||||
)
|
|
||||||
.args(&["Key"])
|
.args(&["Key"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new(
|
MethodProto::new("__setitem__", "PyMappingSetItemProtocol")
|
||||||
"__setitem__",
|
|
||||||
"pyo3::class::mapping::PyMappingSetItemProtocol",
|
|
||||||
)
|
|
||||||
.args(&["Key", "Value"])
|
.args(&["Key", "Value"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new(
|
MethodProto::new("__delitem__", "PyMappingDelItemProtocol")
|
||||||
"__delitem__",
|
|
||||||
"pyo3::class::mapping::PyMappingDelItemProtocol",
|
|
||||||
)
|
|
||||||
.args(&["Key"])
|
.args(&["Key"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new(
|
MethodProto::new("__reversed__", "PyMappingReversedProtocol").has_self(),
|
||||||
"__reversed__",
|
|
||||||
"pyo3::class::mapping::PyMappingReversedProtocol",
|
|
||||||
)
|
|
||||||
.has_self(),
|
|
||||||
],
|
],
|
||||||
py_methods: &[PyMethod::new(
|
py_methods: &[PyMethod::new(
|
||||||
"__reversed__",
|
"__reversed__",
|
||||||
"pyo3::class::mapping::PyMappingReversedProtocolImpl",
|
"PyMappingReversedProtocolImpl",
|
||||||
)],
|
)],
|
||||||
slot_getters: &[
|
slot_defs: &[
|
||||||
SlotGetter::new(&["__len__"], "get_len"),
|
SlotDef::new(&["__len__"], "Py_mp_length", "len"),
|
||||||
SlotGetter::new(&["__getitem__"], "get_getitem"),
|
SlotDef::new(&["__getitem__"], "Py_mp_subscript", "getitem"),
|
||||||
SlotGetter::new(&["__setitem__", "__delitem__"], "get_setdelitem"),
|
SlotDef::new(
|
||||||
SlotGetter::new(&["__setitem__"], "get_setitem"),
|
&["__setitem__", "__delitem__"],
|
||||||
SlotGetter::new(&["__delitem__"], "get_delitem"),
|
"Py_mp_ass_subscript",
|
||||||
|
"setdelitem",
|
||||||
|
),
|
||||||
|
SlotDef::new(&["__setitem__"], "Py_mp_ass_subscript", "setitem"),
|
||||||
|
SlotDef::new(&["__delitem__"], "Py_mp_ass_subscript", "delitem"),
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const SEQ: Proto = Proto {
|
pub const SEQ: Proto = Proto {
|
||||||
name: "Sequence",
|
name: "Sequence",
|
||||||
extension_trait: "pyo3::class::sequence::PySequenceSlots",
|
module: "pyo3::class::sequence",
|
||||||
|
slots_trait: "PySequenceProtocolSlots",
|
||||||
|
slots_trait_slots: "sequence_protocol_slots",
|
||||||
methods: &[
|
methods: &[
|
||||||
MethodProto::new("__len__", "pyo3::class::sequence::PySequenceLenProtocol").has_self(),
|
MethodProto::new("__len__", "PySequenceLenProtocol").has_self(),
|
||||||
MethodProto::new(
|
MethodProto::new("__getitem__", "PySequenceGetItemProtocol")
|
||||||
"__getitem__",
|
|
||||||
"pyo3::class::sequence::PySequenceGetItemProtocol",
|
|
||||||
)
|
|
||||||
.args(&["Index"])
|
.args(&["Index"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new(
|
MethodProto::new("__setitem__", "PySequenceSetItemProtocol")
|
||||||
"__setitem__",
|
|
||||||
"pyo3::class::sequence::PySequenceSetItemProtocol",
|
|
||||||
)
|
|
||||||
.args(&["Index", "Value"])
|
.args(&["Index", "Value"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new(
|
MethodProto::new("__delitem__", "PySequenceDelItemProtocol")
|
||||||
"__delitem__",
|
|
||||||
"pyo3::class::sequence::PySequenceDelItemProtocol",
|
|
||||||
)
|
|
||||||
.args(&["Index"])
|
.args(&["Index"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new(
|
MethodProto::new("__contains__", "PySequenceContainsProtocol")
|
||||||
"__contains__",
|
|
||||||
"pyo3::class::sequence::PySequenceContainsProtocol",
|
|
||||||
)
|
|
||||||
.args(&["Item"])
|
.args(&["Item"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new(
|
MethodProto::new("__concat__", "PySequenceConcatProtocol")
|
||||||
"__concat__",
|
|
||||||
"pyo3::class::sequence::PySequenceConcatProtocol",
|
|
||||||
)
|
|
||||||
.args(&["Other"])
|
.args(&["Other"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new(
|
MethodProto::new("__repeat__", "PySequenceRepeatProtocol")
|
||||||
"__repeat__",
|
|
||||||
"pyo3::class::sequence::PySequenceRepeatProtocol",
|
|
||||||
)
|
|
||||||
.args(&["Index"])
|
.args(&["Index"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new(
|
MethodProto::new("__inplace_concat__", "PySequenceInplaceConcatProtocol")
|
||||||
"__inplace_concat__",
|
|
||||||
"pyo3::class::sequence::PySequenceInplaceConcatProtocol",
|
|
||||||
)
|
|
||||||
.args(&["Other"])
|
.args(&["Other"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new(
|
MethodProto::new("__inplace_repeat__", "PySequenceInplaceRepeatProtocol")
|
||||||
"__inplace_repeat__",
|
|
||||||
"pyo3::class::sequence::PySequenceInplaceRepeatProtocol",
|
|
||||||
)
|
|
||||||
.args(&["Index"])
|
.args(&["Index"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
],
|
],
|
||||||
py_methods: &[],
|
py_methods: &[],
|
||||||
slot_getters: &[
|
slot_defs: &[
|
||||||
SlotGetter::new(&["__len__"], "get_len"),
|
SlotDef::new(&["__len__"], "Py_sq_length", "len"),
|
||||||
SlotGetter::new(&["__concat__"], "get_concat"),
|
SlotDef::new(&["__concat__"], "Py_sq_concat", "concat"),
|
||||||
SlotGetter::new(&["__repeat__"], "get_repeat"),
|
SlotDef::new(&["__repeat__"], "Py_sq_repeat", "repeat"),
|
||||||
SlotGetter::new(&["__getitem__"], "get_getitem"),
|
SlotDef::new(&["__getitem__"], "Py_sq_item", "getitem"),
|
||||||
SlotGetter::new(&["__setitem__", "__delitem__"], "get_setdelitem"),
|
SlotDef::new(
|
||||||
SlotGetter::new(&["__setitem__"], "get_setitem"),
|
&["__setitem__", "__delitem__"],
|
||||||
SlotGetter::new(&["__delitem__"], "get_delitem"),
|
"Py_sq_ass_item",
|
||||||
SlotGetter::new(&["__contains__"], "get_contains"),
|
"setdelitem",
|
||||||
SlotGetter::new(&["__inplace_concat__"], "get_inplace_concat"),
|
),
|
||||||
SlotGetter::new(&["__inplace_repeat__"], "get_inplace_repeat"),
|
SlotDef::new(&["__setitem__"], "Py_sq_ass_item", "setitem"),
|
||||||
|
SlotDef::new(&["__delitem__"], "Py_sq_ass_item", "delitem"),
|
||||||
|
SlotDef::new(&["__contains__"], "Py_sq_contains", "contains"),
|
||||||
|
SlotDef::new(
|
||||||
|
&["__inplace_concat__"],
|
||||||
|
"Py_sq_inplace_concat",
|
||||||
|
"inplace_concat",
|
||||||
|
),
|
||||||
|
SlotDef::new(
|
||||||
|
&["__inplace_repeat__"],
|
||||||
|
"Py_sq_inplace_repeat",
|
||||||
|
"inplace_repeat",
|
||||||
|
),
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const NUM: Proto = Proto {
|
pub const NUM: Proto = Proto {
|
||||||
name: "Number",
|
name: "Number",
|
||||||
extension_trait: "pyo3::class::number::PyNumberSlots",
|
module: "pyo3::class::number",
|
||||||
|
slots_trait: "PyNumberProtocolSlots",
|
||||||
|
slots_trait_slots: "number_protocol_slots",
|
||||||
methods: &[
|
methods: &[
|
||||||
MethodProto::new("__add__", "pyo3::class::number::PyNumberAddProtocol")
|
MethodProto::new("__add__", "PyNumberAddProtocol").args(&["Left", "Right"]),
|
||||||
.args(&["Left", "Right"]),
|
MethodProto::new("__sub__", "PyNumberSubProtocol").args(&["Left", "Right"]),
|
||||||
MethodProto::new("__sub__", "pyo3::class::number::PyNumberSubProtocol")
|
MethodProto::new("__mul__", "PyNumberMulProtocol").args(&["Left", "Right"]),
|
||||||
.args(&["Left", "Right"]),
|
MethodProto::new("__matmul__", "PyNumberMatmulProtocol").args(&["Left", "Right"]),
|
||||||
MethodProto::new("__mul__", "pyo3::class::number::PyNumberMulProtocol")
|
MethodProto::new("__truediv__", "PyNumberTruedivProtocol").args(&["Left", "Right"]),
|
||||||
.args(&["Left", "Right"]),
|
MethodProto::new("__floordiv__", "PyNumberFloordivProtocol").args(&["Left", "Right"]),
|
||||||
MethodProto::new("__matmul__", "pyo3::class::number::PyNumberMatmulProtocol")
|
MethodProto::new("__mod__", "PyNumberModProtocol").args(&["Left", "Right"]),
|
||||||
.args(&["Left", "Right"]),
|
MethodProto::new("__divmod__", "PyNumberDivmodProtocol").args(&["Left", "Right"]),
|
||||||
MethodProto::new(
|
MethodProto::new("__pow__", "PyNumberPowProtocol").args(&["Left", "Right", "Modulo"]),
|
||||||
"__truediv__",
|
MethodProto::new("__lshift__", "PyNumberLShiftProtocol").args(&["Left", "Right"]),
|
||||||
"pyo3::class::number::PyNumberTruedivProtocol",
|
MethodProto::new("__rshift__", "PyNumberRShiftProtocol").args(&["Left", "Right"]),
|
||||||
)
|
MethodProto::new("__and__", "PyNumberAndProtocol").args(&["Left", "Right"]),
|
||||||
.args(&["Left", "Right"]),
|
MethodProto::new("__xor__", "PyNumberXorProtocol").args(&["Left", "Right"]),
|
||||||
MethodProto::new(
|
MethodProto::new("__or__", "PyNumberOrProtocol").args(&["Left", "Right"]),
|
||||||
"__floordiv__",
|
MethodProto::new("__radd__", "PyNumberRAddProtocol")
|
||||||
"pyo3::class::number::PyNumberFloordivProtocol",
|
|
||||||
)
|
|
||||||
.args(&["Left", "Right"]),
|
|
||||||
MethodProto::new("__mod__", "pyo3::class::number::PyNumberModProtocol")
|
|
||||||
.args(&["Left", "Right"]),
|
|
||||||
MethodProto::new("__divmod__", "pyo3::class::number::PyNumberDivmodProtocol")
|
|
||||||
.args(&["Left", "Right"]),
|
|
||||||
MethodProto::new("__pow__", "pyo3::class::number::PyNumberPowProtocol")
|
|
||||||
.args(&["Left", "Right", "Modulo"]),
|
|
||||||
MethodProto::new("__lshift__", "pyo3::class::number::PyNumberLShiftProtocol")
|
|
||||||
.args(&["Left", "Right"]),
|
|
||||||
MethodProto::new("__rshift__", "pyo3::class::number::PyNumberRShiftProtocol")
|
|
||||||
.args(&["Left", "Right"]),
|
|
||||||
MethodProto::new("__and__", "pyo3::class::number::PyNumberAndProtocol")
|
|
||||||
.args(&["Left", "Right"]),
|
|
||||||
MethodProto::new("__xor__", "pyo3::class::number::PyNumberXorProtocol")
|
|
||||||
.args(&["Left", "Right"]),
|
|
||||||
MethodProto::new("__or__", "pyo3::class::number::PyNumberOrProtocol")
|
|
||||||
.args(&["Left", "Right"]),
|
|
||||||
MethodProto::new("__radd__", "pyo3::class::number::PyNumberRAddProtocol")
|
|
||||||
.args(&["Other"])
|
.args(&["Other"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new("__rsub__", "pyo3::class::number::PyNumberRSubProtocol")
|
MethodProto::new("__rsub__", "PyNumberRSubProtocol")
|
||||||
.args(&["Other"])
|
.args(&["Other"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new("__rmul__", "pyo3::class::number::PyNumberRMulProtocol")
|
MethodProto::new("__rmul__", "PyNumberRMulProtocol")
|
||||||
.args(&["Other"])
|
.args(&["Other"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new(
|
MethodProto::new("__rmatmul__", "PyNumberRMatmulProtocol")
|
||||||
"__rmatmul__",
|
|
||||||
"pyo3::class::number::PyNumberRMatmulProtocol",
|
|
||||||
)
|
|
||||||
.args(&["Other"])
|
.args(&["Other"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new(
|
MethodProto::new("__rtruediv__", "PyNumberRTruedivProtocol")
|
||||||
"__rtruediv__",
|
|
||||||
"pyo3::class::number::PyNumberRTruedivProtocol",
|
|
||||||
)
|
|
||||||
.args(&["Other"])
|
.args(&["Other"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new(
|
MethodProto::new("__rfloordiv__", "PyNumberRFloordivProtocol")
|
||||||
"__rfloordiv__",
|
|
||||||
"pyo3::class::number::PyNumberRFloordivProtocol",
|
|
||||||
)
|
|
||||||
.args(&["Other"])
|
.args(&["Other"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new("__rmod__", "pyo3::class::number::PyNumberRModProtocol")
|
MethodProto::new("__rmod__", "PyNumberRModProtocol")
|
||||||
.args(&["Other"])
|
.args(&["Other"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new(
|
MethodProto::new("__rdivmod__", "PyNumberRDivmodProtocol")
|
||||||
"__rdivmod__",
|
|
||||||
"pyo3::class::number::PyNumberRDivmodProtocol",
|
|
||||||
)
|
|
||||||
.args(&["Other"])
|
.args(&["Other"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new("__rpow__", "pyo3::class::number::PyNumberRPowProtocol")
|
MethodProto::new("__rpow__", "PyNumberRPowProtocol")
|
||||||
.args(&["Other", "Modulo"])
|
.args(&["Other", "Modulo"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new(
|
MethodProto::new("__rlshift__", "PyNumberRLShiftProtocol")
|
||||||
"__rlshift__",
|
|
||||||
"pyo3::class::number::PyNumberRLShiftProtocol",
|
|
||||||
)
|
|
||||||
.args(&["Other"])
|
.args(&["Other"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new(
|
MethodProto::new("__rrshift__", "PyNumberRRShiftProtocol")
|
||||||
"__rrshift__",
|
|
||||||
"pyo3::class::number::PyNumberRRShiftProtocol",
|
|
||||||
)
|
|
||||||
.args(&["Other"])
|
.args(&["Other"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new("__rand__", "pyo3::class::number::PyNumberRAndProtocol")
|
MethodProto::new("__rand__", "PyNumberRAndProtocol")
|
||||||
.args(&["Other"])
|
.args(&["Other"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new("__rxor__", "pyo3::class::number::PyNumberRXorProtocol")
|
MethodProto::new("__rxor__", "PyNumberRXorProtocol")
|
||||||
.args(&["Other"])
|
.args(&["Other"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new("__ror__", "pyo3::class::number::PyNumberROrProtocol")
|
MethodProto::new("__ror__", "PyNumberROrProtocol")
|
||||||
.args(&["Other"])
|
.args(&["Other"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new("__iadd__", "pyo3::class::number::PyNumberIAddProtocol")
|
MethodProto::new("__iadd__", "PyNumberIAddProtocol")
|
||||||
.args(&["Other"])
|
.args(&["Other"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new("__isub__", "pyo3::class::number::PyNumberISubProtocol")
|
MethodProto::new("__isub__", "PyNumberISubProtocol")
|
||||||
.args(&["Other"])
|
.args(&["Other"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new("__imul__", "pyo3::class::number::PyNumberIMulProtocol")
|
MethodProto::new("__imul__", "PyNumberIMulProtocol")
|
||||||
.args(&["Other"])
|
.args(&["Other"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new(
|
MethodProto::new("__imatmul__", "PyNumberIMatmulProtocol")
|
||||||
"__imatmul__",
|
|
||||||
"pyo3::class::number::PyNumberIMatmulProtocol",
|
|
||||||
)
|
|
||||||
.args(&["Other"])
|
.args(&["Other"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new(
|
MethodProto::new("__itruediv__", "PyNumberITruedivProtocol")
|
||||||
"__itruediv__",
|
|
||||||
"pyo3::class::number::PyNumberITruedivProtocol",
|
|
||||||
)
|
|
||||||
.args(&["Other"])
|
.args(&["Other"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new(
|
MethodProto::new("__ifloordiv__", "PyNumberIFloordivProtocol")
|
||||||
"__ifloordiv__",
|
|
||||||
"pyo3::class::number::PyNumberIFloordivProtocol",
|
|
||||||
)
|
|
||||||
.args(&["Other"])
|
.args(&["Other"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new("__imod__", "pyo3::class::number::PyNumberIModProtocol")
|
MethodProto::new("__imod__", "PyNumberIModProtocol")
|
||||||
.args(&["Other"])
|
.args(&["Other"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new("__ipow__", "pyo3::class::number::PyNumberIPowProtocol")
|
MethodProto::new("__ipow__", "PyNumberIPowProtocol")
|
||||||
.args(&["Other"])
|
.args(&["Other"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new(
|
MethodProto::new("__ilshift__", "PyNumberILShiftProtocol")
|
||||||
"__ilshift__",
|
|
||||||
"pyo3::class::number::PyNumberILShiftProtocol",
|
|
||||||
)
|
|
||||||
.args(&["Other"])
|
.args(&["Other"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new(
|
MethodProto::new("__irshift__", "PyNumberIRShiftProtocol")
|
||||||
"__irshift__",
|
|
||||||
"pyo3::class::number::PyNumberIRShiftProtocol",
|
|
||||||
)
|
|
||||||
.args(&["Other"])
|
.args(&["Other"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new("__iand__", "pyo3::class::number::PyNumberIAndProtocol")
|
MethodProto::new("__iand__", "PyNumberIAndProtocol")
|
||||||
.args(&["Other"])
|
.args(&["Other"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new("__ixor__", "pyo3::class::number::PyNumberIXorProtocol")
|
MethodProto::new("__ixor__", "PyNumberIXorProtocol")
|
||||||
.args(&["Other"])
|
.args(&["Other"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new("__ior__", "pyo3::class::number::PyNumberIOrProtocol")
|
MethodProto::new("__ior__", "PyNumberIOrProtocol")
|
||||||
.args(&["Other"])
|
.args(&["Other"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
MethodProto::new("__neg__", "pyo3::class::number::PyNumberNegProtocol").has_self(),
|
MethodProto::new("__neg__", "PyNumberNegProtocol").has_self(),
|
||||||
MethodProto::new("__pos__", "pyo3::class::number::PyNumberPosProtocol").has_self(),
|
MethodProto::new("__pos__", "PyNumberPosProtocol").has_self(),
|
||||||
MethodProto::new("__abs__", "pyo3::class::number::PyNumberAbsProtocol").has_self(),
|
MethodProto::new("__abs__", "PyNumberAbsProtocol").has_self(),
|
||||||
MethodProto::new("__invert__", "pyo3::class::number::PyNumberInvertProtocol").has_self(),
|
MethodProto::new("__invert__", "PyNumberInvertProtocol").has_self(),
|
||||||
MethodProto::new(
|
MethodProto::new("__complex__", "PyNumberComplexProtocol").has_self(),
|
||||||
"__complex__",
|
MethodProto::new("__int__", "PyNumberIntProtocol").has_self(),
|
||||||
"pyo3::class::number::PyNumberComplexProtocol",
|
MethodProto::new("__float__", "PyNumberFloatProtocol").has_self(),
|
||||||
)
|
MethodProto::new("__index__", "PyNumberIndexProtocol").has_self(),
|
||||||
.has_self(),
|
MethodProto::new("__round__", "PyNumberRoundProtocol")
|
||||||
MethodProto::new("__int__", "pyo3::class::number::PyNumberIntProtocol").has_self(),
|
|
||||||
MethodProto::new("__float__", "pyo3::class::number::PyNumberFloatProtocol").has_self(),
|
|
||||||
MethodProto::new("__index__", "pyo3::class::number::PyNumberIndexProtocol").has_self(),
|
|
||||||
MethodProto::new("__round__", "pyo3::class::number::PyNumberRoundProtocol")
|
|
||||||
.args(&["NDigits"])
|
.args(&["NDigits"])
|
||||||
.has_self(),
|
.has_self(),
|
||||||
],
|
],
|
||||||
py_methods: &[
|
py_methods: &[
|
||||||
PyMethod::coexist("__radd__", "pyo3::class::number::PyNumberRAddProtocolImpl"),
|
PyMethod::coexist("__radd__", "PyNumberRAddProtocolImpl"),
|
||||||
PyMethod::coexist("__rsub__", "pyo3::class::number::PyNumberRSubProtocolImpl"),
|
PyMethod::coexist("__rsub__", "PyNumberRSubProtocolImpl"),
|
||||||
PyMethod::coexist("__rmul__", "pyo3::class::number::PyNumberRMulProtocolImpl"),
|
PyMethod::coexist("__rmul__", "PyNumberRMulProtocolImpl"),
|
||||||
PyMethod::coexist(
|
PyMethod::coexist("__rmatmul__", "PyNumberRMatmulProtocolImpl"),
|
||||||
"__rmatmul__",
|
PyMethod::coexist("__rtruediv__", "PyNumberRTruedivProtocolImpl"),
|
||||||
"pyo3::class::number::PyNumberRMatmulProtocolImpl",
|
PyMethod::coexist("__rfloordiv__", "PyNumberRFloordivProtocolImpl"),
|
||||||
),
|
PyMethod::coexist("__rmod__", "PyNumberRModProtocolImpl"),
|
||||||
PyMethod::coexist(
|
PyMethod::coexist("__rdivmod__", "PyNumberRDivmodProtocolImpl"),
|
||||||
"__rtruediv__",
|
PyMethod::coexist("__rpow__", "PyNumberRPowProtocolImpl"),
|
||||||
"pyo3::class::number::PyNumberRTruedivProtocolImpl",
|
PyMethod::coexist("__rlshift__", "PyNumberRLShiftProtocolImpl"),
|
||||||
),
|
PyMethod::coexist("__rrshift__", "PyNumberRRShiftProtocolImpl"),
|
||||||
PyMethod::coexist(
|
PyMethod::coexist("__rand__", "PyNumberRAndProtocolImpl"),
|
||||||
"__rfloordiv__",
|
PyMethod::coexist("__rxor__", "PyNumberRXorProtocolImpl"),
|
||||||
"pyo3::class::number::PyNumberRFloordivProtocolImpl",
|
PyMethod::coexist("__ror__", "PyNumberROrProtocolImpl"),
|
||||||
),
|
PyMethod::new("__complex__", "PyNumberComplexProtocolImpl"),
|
||||||
PyMethod::coexist("__rmod__", "pyo3::class::number::PyNumberRModProtocolImpl"),
|
PyMethod::new("__round__", "PyNumberRoundProtocolImpl"),
|
||||||
PyMethod::coexist(
|
|
||||||
"__rdivmod__",
|
|
||||||
"pyo3::class::number::PyNumberRDivmodProtocolImpl",
|
|
||||||
),
|
|
||||||
PyMethod::coexist("__rpow__", "pyo3::class::number::PyNumberRPowProtocolImpl"),
|
|
||||||
PyMethod::coexist(
|
|
||||||
"__rlshift__",
|
|
||||||
"pyo3::class::number::PyNumberRLShiftProtocolImpl",
|
|
||||||
),
|
|
||||||
PyMethod::coexist(
|
|
||||||
"__rrshift__",
|
|
||||||
"pyo3::class::number::PyNumberRRShiftProtocolImpl",
|
|
||||||
),
|
|
||||||
PyMethod::coexist("__rand__", "pyo3::class::number::PyNumberRAndProtocolImpl"),
|
|
||||||
PyMethod::coexist("__rxor__", "pyo3::class::number::PyNumberRXorProtocolImpl"),
|
|
||||||
PyMethod::coexist("__ror__", "pyo3::class::number::PyNumberROrProtocolImpl"),
|
|
||||||
PyMethod::new(
|
|
||||||
"__complex__",
|
|
||||||
"pyo3::class::number::PyNumberComplexProtocolImpl",
|
|
||||||
),
|
|
||||||
PyMethod::new(
|
|
||||||
"__round__",
|
|
||||||
"pyo3::class::number::PyNumberRoundProtocolImpl",
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
slot_getters: &[
|
slot_defs: &[
|
||||||
SlotGetter::new(&["__add__", "__radd__"], "get_add_radd"),
|
SlotDef::new(&["__add__", "__radd__"], "Py_nb_add", "add_radd"),
|
||||||
SlotGetter::new(&["__add__"], "get_add"),
|
SlotDef::new(&["__add__"], "Py_nb_add", "add"),
|
||||||
SlotGetter::new(&["__radd__"], "get_radd"),
|
SlotDef::new(&["__radd__"], "Py_nb_add", "radd"),
|
||||||
SlotGetter::new(&["__sub__", "__rsub__"], "get_sub_rsub"),
|
SlotDef::new(&["__sub__", "__rsub__"], "Py_nb_subtract", "sub_rsub"),
|
||||||
SlotGetter::new(&["__sub__"], "get_sub"),
|
SlotDef::new(&["__sub__"], "Py_nb_subtract", "sub"),
|
||||||
SlotGetter::new(&["__rsub__"], "get_rsub"),
|
SlotDef::new(&["__rsub__"], "Py_nb_subtract", "rsub"),
|
||||||
SlotGetter::new(&["__mul__", "__rmul__"], "get_mul_rmul"),
|
SlotDef::new(&["__mul__", "__rmul__"], "Py_nb_multiply", "mul_rmul"),
|
||||||
SlotGetter::new(&["__mul__"], "get_mul"),
|
SlotDef::new(&["__mul__"], "Py_nb_multiply", "mul"),
|
||||||
SlotGetter::new(&["__rmul__"], "get_rmul"),
|
SlotDef::new(&["__rmul__"], "Py_nb_multiply", "rmul"),
|
||||||
SlotGetter::new(&["__mod__"], "get_mod"),
|
SlotDef::new(&["__mod__"], "Py_nb_remainder", "mod_"),
|
||||||
SlotGetter::new(&["__divmod__", "__rdivmod__"], "get_divmod_rdivmod"),
|
SlotDef::new(
|
||||||
SlotGetter::new(&["__divmod__"], "get_divmod"),
|
&["__divmod__", "__rdivmod__"],
|
||||||
SlotGetter::new(&["__rdivmod__"], "get_rdivmod"),
|
"Py_nb_divmod",
|
||||||
SlotGetter::new(&["__pow__", "__rpow__"], "get_pow_rpow"),
|
"divmod_rdivmod",
|
||||||
SlotGetter::new(&["__pow__"], "get_pow"),
|
),
|
||||||
SlotGetter::new(&["__rpow__"], "get_rpow"),
|
SlotDef::new(&["__divmod__"], "Py_nb_divmod", "divmod"),
|
||||||
SlotGetter::new(&["__neg__"], "get_neg"),
|
SlotDef::new(&["__rdivmod__"], "Py_nb_divmod", "rdivmod"),
|
||||||
SlotGetter::new(&["__pos__"], "get_pos"),
|
SlotDef::new(&["__pow__", "__rpow__"], "Py_nb_power", "pow_rpow"),
|
||||||
SlotGetter::new(&["__abs__"], "get_abs"),
|
SlotDef::new(&["__pow__"], "Py_nb_power", "pow"),
|
||||||
SlotGetter::new(&["__invert__"], "get_invert"),
|
SlotDef::new(&["__rpow__"], "Py_nb_power", "rpow"),
|
||||||
SlotGetter::new(&["__lshift__", "__rlshift__"], "get_lshift_rlshift"),
|
SlotDef::new(&["__neg__"], "Py_nb_negative", "neg"),
|
||||||
SlotGetter::new(&["__lshift__"], "get_lshift"),
|
SlotDef::new(&["__pos__"], "Py_nb_positive", "pos"),
|
||||||
SlotGetter::new(&["__rlshift__"], "get_rlshift"),
|
SlotDef::new(&["__abs__"], "Py_nb_absolute", "abs"),
|
||||||
SlotGetter::new(&["__rshift__", "__rrshift__"], "get_rshift_rrshift"),
|
SlotDef::new(&["__invert__"], "Py_nb_invert", "invert"),
|
||||||
SlotGetter::new(&["__rshift__"], "get_rshift"),
|
SlotDef::new(
|
||||||
SlotGetter::new(&["__rrshift__"], "get_rrshift"),
|
&["__lshift__", "__rlshift__"],
|
||||||
SlotGetter::new(&["__and__", "__rand__"], "get_and_rand"),
|
"Py_nb_lshift",
|
||||||
SlotGetter::new(&["__and__"], "get_and"),
|
"lshift_rlshift",
|
||||||
SlotGetter::new(&["__rand__"], "get_rand"),
|
),
|
||||||
SlotGetter::new(&["__xor__", "__rxor__"], "get_xor_rxor"),
|
SlotDef::new(&["__lshift__"], "Py_nb_lshift", "lshift"),
|
||||||
SlotGetter::new(&["__xor__"], "get_xor"),
|
SlotDef::new(&["__rlshift__"], "Py_nb_lshift", "rlshift"),
|
||||||
SlotGetter::new(&["__rxor__"], "get_rxor"),
|
SlotDef::new(
|
||||||
SlotGetter::new(&["__or__", "__ror__"], "get_or_ror"),
|
&["__rshift__", "__rrshift__"],
|
||||||
SlotGetter::new(&["__or__"], "get_or"),
|
"Py_nb_rshift",
|
||||||
SlotGetter::new(&["__ror__"], "get_ror"),
|
"rshift_rrshift",
|
||||||
SlotGetter::new(&["__int__"], "get_int"),
|
),
|
||||||
SlotGetter::new(&["__float__"], "get_float"),
|
SlotDef::new(&["__rshift__"], "Py_nb_rshift", "rshift"),
|
||||||
SlotGetter::new(&["__iadd__"], "get_iadd"),
|
SlotDef::new(&["__rrshift__"], "Py_nb_rshift", "rrshift"),
|
||||||
SlotGetter::new(&["__isub__"], "get_isub"),
|
SlotDef::new(&["__and__", "__rand__"], "Py_nb_and", "and_rand"),
|
||||||
SlotGetter::new(&["__imul__"], "get_imul"),
|
SlotDef::new(&["__and__"], "Py_nb_and", "and"),
|
||||||
SlotGetter::new(&["__imod__"], "get_imod"),
|
SlotDef::new(&["__rand__"], "Py_nb_and", "rand"),
|
||||||
SlotGetter::new(&["__ipow__"], "get_ipow"),
|
SlotDef::new(&["__xor__", "__rxor__"], "Py_nb_xor", "xor_rxor"),
|
||||||
SlotGetter::new(&["__ilshift__"], "get_ilshift"),
|
SlotDef::new(&["__xor__"], "Py_nb_xor", "xor"),
|
||||||
SlotGetter::new(&["__irshift__"], "get_irshift"),
|
SlotDef::new(&["__rxor__"], "Py_nb_xor", "rxor"),
|
||||||
SlotGetter::new(&["__iand__"], "get_iand"),
|
SlotDef::new(&["__or__", "__ror__"], "Py_nb_or", "or_ror"),
|
||||||
SlotGetter::new(&["__ixor__"], "get_ixor"),
|
SlotDef::new(&["__or__"], "Py_nb_or", "or"),
|
||||||
SlotGetter::new(&["__ior__"], "get_ior"),
|
SlotDef::new(&["__ror__"], "Py_nb_or", "ror"),
|
||||||
SlotGetter::new(&["__floordiv__", "__rfloordiv__"], "get_floordiv_rfloordiv"),
|
SlotDef::new(&["__int__"], "Py_nb_int", "int"),
|
||||||
SlotGetter::new(&["__floordiv__"], "get_floordiv"),
|
SlotDef::new(&["__float__"], "Py_nb_float", "float"),
|
||||||
SlotGetter::new(&["__rfloordiv__"], "get_rfloordiv"),
|
SlotDef::new(&["__iadd__"], "Py_nb_inplace_add", "iadd"),
|
||||||
SlotGetter::new(&["__truediv__", "__rtruediv__"], "get_truediv_rtruediv"),
|
SlotDef::new(&["__isub__"], "Py_nb_inplace_subtract", "isub"),
|
||||||
SlotGetter::new(&["__truediv__"], "get_truediv"),
|
SlotDef::new(&["__imul__"], "Py_nb_inplace_multiply", "imul"),
|
||||||
SlotGetter::new(&["__rtruediv__"], "get_rtruediv"),
|
SlotDef::new(&["__imod__"], "Py_nb_inplace_remainder", "imod"),
|
||||||
SlotGetter::new(&["__ifloordiv__"], "get_ifloordiv"),
|
SlotDef::new(&["__ipow__"], "Py_nb_inplace_power", "ipow"),
|
||||||
SlotGetter::new(&["__itruediv__"], "get_itruediv"),
|
SlotDef::new(&["__ilshift__"], "Py_nb_inplace_lshift", "ilshift"),
|
||||||
SlotGetter::new(&["__index__"], "get_index"),
|
SlotDef::new(&["__irshift__"], "Py_nb_inplace_rshift", "irshift"),
|
||||||
SlotGetter::new(&["__matmul__", "__rmatmul__"], "get_matmul_rmatmul"),
|
SlotDef::new(&["__iand__"], "Py_nb_inplace_and", "iand"),
|
||||||
SlotGetter::new(&["__matmul__"], "get_matmul"),
|
SlotDef::new(&["__ixor__"], "Py_nb_inplace_xor", "ixor"),
|
||||||
SlotGetter::new(&["__rmatmul__"], "get_rmatmul"),
|
SlotDef::new(&["__ior__"], "Py_nb_inplace_or", "ior"),
|
||||||
SlotGetter::new(&["__imatmul__"], "get_imatmul"),
|
SlotDef::new(
|
||||||
|
&["__floordiv__", "__rfloordiv__"],
|
||||||
|
"Py_nb_floor_divide",
|
||||||
|
"floordiv_rfloordiv",
|
||||||
|
),
|
||||||
|
SlotDef::new(&["__floordiv__"], "Py_nb_floor_divide", "floordiv"),
|
||||||
|
SlotDef::new(&["__rfloordiv__"], "Py_nb_floor_divide", "rfloordiv"),
|
||||||
|
SlotDef::new(
|
||||||
|
&["__truediv__", "__rtruediv__"],
|
||||||
|
"Py_nb_true_divide",
|
||||||
|
"truediv_rtruediv",
|
||||||
|
),
|
||||||
|
SlotDef::new(&["__truediv__"], "Py_nb_true_divide", "truediv"),
|
||||||
|
SlotDef::new(&["__rtruediv__"], "Py_nb_true_divide", "rtruediv"),
|
||||||
|
SlotDef::new(
|
||||||
|
&["__ifloordiv__"],
|
||||||
|
"Py_nb_inplace_floor_divide",
|
||||||
|
"ifloordiv",
|
||||||
|
),
|
||||||
|
SlotDef::new(&["__itruediv__"], "Py_nb_inplace_true_divide", "itruediv"),
|
||||||
|
SlotDef::new(&["__index__"], "Py_nb_index", "index"),
|
||||||
|
SlotDef::new(
|
||||||
|
&["__matmul__", "__rmatmul__"],
|
||||||
|
"Py_nb_matrix_multiply",
|
||||||
|
"matmul_rmatmul",
|
||||||
|
),
|
||||||
|
SlotDef::new(&["__matmul__"], "Py_nb_matrix_multiply", "matmul"),
|
||||||
|
SlotDef::new(&["__rmatmul__"], "Py_nb_matrix_multiply", "rmatmul"),
|
||||||
|
SlotDef::new(&["__imatmul__"], "Py_nb_inplace_matrix_multiply", "imatmul"),
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
|
@ -43,9 +43,10 @@ impl MethodProto {
|
||||||
pub(crate) fn impl_method_proto(
|
pub(crate) fn impl_method_proto(
|
||||||
cls: &syn::Type,
|
cls: &syn::Type,
|
||||||
sig: &mut syn::Signature,
|
sig: &mut syn::Signature,
|
||||||
|
module: &syn::Path,
|
||||||
meth: &MethodProto,
|
meth: &MethodProto,
|
||||||
) -> syn::Result<TokenStream> {
|
) -> syn::Result<TokenStream> {
|
||||||
let p: syn::Path = syn::parse_str(meth.proto).unwrap();
|
let proto: syn::Path = syn::parse_str(meth.proto).unwrap();
|
||||||
|
|
||||||
let mut impl_types = Vec::new();
|
let mut impl_types = Vec::new();
|
||||||
for (i, arg) in meth.args.iter().enumerate() {
|
for (i, arg) in meth.args.iter().enumerate() {
|
||||||
|
@ -55,8 +56,8 @@ pub(crate) fn impl_method_proto(
|
||||||
|
|
||||||
impl_types.push(quote! {type #arg_name = #arg_ty;});
|
impl_types.push(quote! {type #arg_name = #arg_ty;});
|
||||||
|
|
||||||
let type1 = syn::parse_quote! { arg: <#cls as #p<'p>>::#arg_name};
|
let type1 = syn::parse_quote! { arg: <#cls as #module::#proto<'p>>::#arg_name};
|
||||||
let type2 = syn::parse_quote! { arg: Option<<#cls as #p<'p>>::#arg_name>};
|
let type2 = syn::parse_quote! { arg: Option<<#cls as #module::#proto<'p>>::#arg_name>};
|
||||||
modify_arg_ty(sig, idx, &type1, &type2)?;
|
modify_arg_ty(sig, idx, &type1, &type2)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,14 +75,14 @@ pub(crate) fn impl_method_proto(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
sig.output = syn::parse_quote! { -> <#cls as #p<'p>>::Result };
|
sig.output = syn::parse_quote! { -> <#cls as #module::#proto<'p>>::Result };
|
||||||
quote! { type Result = #ret_ty; }
|
quote! { type Result = #ret_ty; }
|
||||||
} else {
|
} else {
|
||||||
proc_macro2::TokenStream::new()
|
proc_macro2::TokenStream::new()
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(quote! {
|
Ok(quote! {
|
||||||
impl<'p> #p<'p> for #cls {
|
impl<'p> #module::#proto<'p> for #cls {
|
||||||
#(#impl_types)*
|
#(#impl_types)*
|
||||||
#res_type_def
|
#res_type_def
|
||||||
}
|
}
|
||||||
|
|
|
@ -254,34 +254,6 @@ fn impl_methods_inventory(cls: &syn::Ident) -> TokenStream {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Implement `HasProtoInventory` for the class for lazy protocol initialization.
|
|
||||||
fn impl_proto_inventory(cls: &syn::Ident) -> TokenStream {
|
|
||||||
// Try to build a unique type for better error messages
|
|
||||||
let name = format!("Pyo3ProtoInventoryFor{}", cls);
|
|
||||||
let inventory_cls = syn::Ident::new(&name, Span::call_site());
|
|
||||||
|
|
||||||
quote! {
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub struct #inventory_cls {
|
|
||||||
def: pyo3::class::proto_methods::PyProtoMethodDef,
|
|
||||||
}
|
|
||||||
impl pyo3::class::proto_methods::PyProtoInventory for #inventory_cls {
|
|
||||||
fn new(def: pyo3::class::proto_methods::PyProtoMethodDef) -> Self {
|
|
||||||
Self { def }
|
|
||||||
}
|
|
||||||
fn get(&'static self) -> &'static pyo3::class::proto_methods::PyProtoMethodDef {
|
|
||||||
&self.def
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl pyo3::class::proto_methods::HasProtoInventory for #cls {
|
|
||||||
type ProtoMethods = #inventory_cls;
|
|
||||||
}
|
|
||||||
|
|
||||||
pyo3::inventory::collect!(#inventory_cls);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_class_python_name<'a>(cls: &'a syn::Ident, attr: &'a PyClassArgs) -> &'a syn::Ident {
|
fn get_class_python_name<'a>(cls: &'a syn::Ident, attr: &'a PyClassArgs) -> &'a syn::Ident {
|
||||||
attr.name.as_ref().unwrap_or(cls)
|
attr.name.as_ref().unwrap_or(cls)
|
||||||
}
|
}
|
||||||
|
@ -383,7 +355,6 @@ fn impl_class(
|
||||||
};
|
};
|
||||||
|
|
||||||
let impl_inventory = impl_methods_inventory(&cls);
|
let impl_inventory = impl_methods_inventory(&cls);
|
||||||
let impl_proto_inventory = impl_proto_inventory(&cls);
|
|
||||||
|
|
||||||
let base = &attr.base;
|
let base = &attr.base;
|
||||||
let flags = &attr.flags;
|
let flags = &attr.flags;
|
||||||
|
@ -472,7 +443,32 @@ fn impl_class(
|
||||||
|
|
||||||
#impl_inventory
|
#impl_inventory
|
||||||
|
|
||||||
#impl_proto_inventory
|
impl pyo3::class::proto_methods::PyProtoMethods for #cls {
|
||||||
|
fn for_each_proto_slot<Visitor: FnMut(pyo3::ffi::PyType_Slot)>(visitor: Visitor) {
|
||||||
|
// Implementation which uses dtolnay specialization to load all slots.
|
||||||
|
use pyo3::class::proto_methods::*;
|
||||||
|
let protocols = PyClassProtocols::<#cls>::new();
|
||||||
|
protocols.object_protocol_slots()
|
||||||
|
.iter()
|
||||||
|
.chain(protocols.number_protocol_slots())
|
||||||
|
.chain(protocols.iter_protocol_slots())
|
||||||
|
.chain(protocols.gc_protocol_slots())
|
||||||
|
.chain(protocols.descr_protocol_slots())
|
||||||
|
.chain(protocols.mapping_protocol_slots())
|
||||||
|
.chain(protocols.sequence_protocol_slots())
|
||||||
|
.chain(protocols.async_protocol_slots())
|
||||||
|
.chain(protocols.buffer_protocol_slots())
|
||||||
|
.cloned()
|
||||||
|
.for_each(visitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_buffer() -> Option<&'static pyo3::class::proto_methods::PyBufferProcs> {
|
||||||
|
use pyo3::class::proto_methods::*;
|
||||||
|
let protocols = PyClassProtocols::<#cls>::new();
|
||||||
|
protocols.buffer_procs()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#extra
|
#extra
|
||||||
|
|
||||||
|
|
|
@ -62,12 +62,13 @@ fn impl_proto_impl(
|
||||||
let mut trait_impls = TokenStream::new();
|
let mut trait_impls = TokenStream::new();
|
||||||
let mut py_methods = Vec::new();
|
let mut py_methods = Vec::new();
|
||||||
let mut method_names = HashSet::new();
|
let mut method_names = HashSet::new();
|
||||||
|
let module = proto.module();
|
||||||
|
|
||||||
for iimpl in impls.iter_mut() {
|
for iimpl in impls.iter_mut() {
|
||||||
if let syn::ImplItem::Method(met) = iimpl {
|
if let syn::ImplItem::Method(met) = iimpl {
|
||||||
// impl Py~Protocol<'p> { type = ... }
|
// impl Py~Protocol<'p> { type = ... }
|
||||||
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 trait_impls);
|
impl_method_proto(ty, &mut met.sig, &module, m)?.to_tokens(&mut trait_impls);
|
||||||
// Insert the method to the HashSet
|
// Insert the method to the HashSet
|
||||||
method_names.insert(met.sig.ident.to_string());
|
method_names.insert(met.sig.ident.to_string());
|
||||||
}
|
}
|
||||||
|
@ -107,7 +108,7 @@ fn impl_proto_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let normal_methods = submit_normal_methods(py_methods, ty);
|
let normal_methods = submit_normal_methods(py_methods, ty);
|
||||||
let protocol_methods = submit_protocol_methods(method_names, ty, proto)?;
|
let protocol_methods = impl_proto_methods(method_names, ty, proto);
|
||||||
Ok(quote! {
|
Ok(quote! {
|
||||||
#trait_impls
|
#trait_impls
|
||||||
#normal_methods
|
#normal_methods
|
||||||
|
@ -129,49 +130,69 @@ fn submit_normal_methods(py_methods: Vec<TokenStream>, ty: &syn::Type) -> TokenS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn submit_protocol_methods(
|
fn impl_proto_methods(
|
||||||
method_names: HashSet<String>,
|
method_names: HashSet<String>,
|
||||||
ty: &syn::Type,
|
ty: &syn::Type,
|
||||||
proto: &defs::Proto,
|
proto: &defs::Proto,
|
||||||
) -> syn::Result<TokenStream> {
|
) -> TokenStream {
|
||||||
if proto.extension_trait == "" {
|
if proto.slots_trait.is_empty() {
|
||||||
return Ok(quote! {});
|
return TokenStream::default();
|
||||||
}
|
}
|
||||||
let ext_trait: syn::Path = syn::parse_str(proto.extension_trait)?;
|
|
||||||
let mut tokens = vec![];
|
let module = proto.module();
|
||||||
|
let slots_trait = syn::Ident::new(proto.slots_trait, Span::call_site());
|
||||||
|
let slots_trait_slots = syn::Ident::new(proto.slots_trait_slots, Span::call_site());
|
||||||
|
|
||||||
|
let mut maybe_buffer_methods = None;
|
||||||
if proto.name == "Buffer" {
|
if proto.name == "Buffer" {
|
||||||
// For buffer, we construct `PyProtoMethods` from PyBufferProcs
|
// On Python 3.9 we have to use PyBufferProcs to set buffer slots.
|
||||||
tokens.push(quote! {
|
// For now we emit this always for buffer methods, even on 3.9+.
|
||||||
let mut proto_methods = pyo3::ffi::PyBufferProcs::default();
|
// Maybe in the future we can access Py_3_9 here and define it.
|
||||||
});
|
maybe_buffer_methods = Some(quote! {
|
||||||
for getter in proto.slot_getters(method_names) {
|
impl pyo3::class::proto_methods::PyBufferProtocolProcs<#ty>
|
||||||
let get = syn::Ident::new(getter, Span::call_site());
|
for pyo3::class::proto_methods::PyClassProtocols<#ty>
|
||||||
let field = syn::Ident::new(&format!("bf_{}", &getter[4..]), Span::call_site());
|
{
|
||||||
tokens.push(quote! { proto_methods.#field = Some(<#ty as #ext_trait>::#get()); });
|
fn buffer_procs(
|
||||||
}
|
self
|
||||||
} else {
|
) -> Option<&'static pyo3::class::proto_methods::PyBufferProcs> {
|
||||||
// For other protocols, we construct `PyProtoMethods` from Vec<ffi::PyType_Slot>
|
static PROCS: pyo3::class::proto_methods::PyBufferProcs
|
||||||
tokens.push(quote! { let mut proto_methods = vec![]; });
|
= pyo3::class::proto_methods::PyBufferProcs {
|
||||||
for getter in proto.slot_getters(method_names) {
|
bf_getbuffer: Some(pyo3::class::buffer::getbuffer::<#ty>),
|
||||||
let get = syn::Ident::new(getter, Span::call_site());
|
bf_releasebuffer: Some(pyo3::class::buffer::releasebuffer::<#ty>),
|
||||||
tokens.push(quote! {
|
|
||||||
let slot = <#ty as #ext_trait>::#get();
|
|
||||||
proto_methods.push(pyo3::ffi::PyType_Slot { slot: slot.0, pfunc: slot.1 as _ });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
if tokens.len() <= 1 {
|
Some(&PROCS)
|
||||||
return Ok(quote! {});
|
|
||||||
}
|
|
||||||
Ok(quote! {
|
|
||||||
pyo3::inventory::submit! {
|
|
||||||
#![crate = pyo3] {
|
|
||||||
type Inventory =
|
|
||||||
<#ty as pyo3::class::proto_methods::HasProtoInventory>::ProtoMethods;
|
|
||||||
<Inventory as pyo3::class::proto_methods::PyProtoInventory>::new(
|
|
||||||
{ #(#tokens)* proto_methods.into() }
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut tokens = proto
|
||||||
|
.slot_defs(method_names)
|
||||||
|
.map(|def| {
|
||||||
|
let slot = syn::Ident::new(def.slot, Span::call_site());
|
||||||
|
let slot_impl = syn::Ident::new(def.slot_impl, Span::call_site());
|
||||||
|
quote! {{
|
||||||
|
pyo3::ffi::PyType_Slot {
|
||||||
|
slot: pyo3::ffi::#slot,
|
||||||
|
pfunc: #module::#slot_impl::<#ty> as _
|
||||||
|
}
|
||||||
|
}}
|
||||||
})
|
})
|
||||||
|
.peekable();
|
||||||
|
|
||||||
|
if tokens.peek().is_none() {
|
||||||
|
return TokenStream::default();
|
||||||
|
}
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
#maybe_buffer_methods
|
||||||
|
|
||||||
|
impl pyo3::class::proto_methods::#slots_trait<#ty>
|
||||||
|
for pyo3::class::proto_methods::PyClassProtocols<#ty>
|
||||||
|
{
|
||||||
|
fn #slots_trait_slots(self) -> &'static [pyo3::ffi::PyType_Slot] {
|
||||||
|
&[#(#tokens),*]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,8 @@
|
||||||
//! Parts of the documentation are copied from the respective methods from the
|
//! Parts of the documentation are copied from the respective methods from the
|
||||||
//! [typeobj docs](https://docs.python.org/3/c-api/typeobj.html)
|
//! [typeobj docs](https://docs.python.org/3/c-api/typeobj.html)
|
||||||
|
|
||||||
use super::proto_methods::TypedSlot;
|
|
||||||
use crate::callback::{HashCallbackOutput, IntoPyCallbackOutput};
|
use crate::callback::{HashCallbackOutput, IntoPyCallbackOutput};
|
||||||
use crate::{exceptions, ffi, FromPyObject, PyAny, PyCell, PyClass, PyObject, PyResult};
|
use crate::{exceptions, ffi, FromPyObject, PyAny, PyCell, PyClass, PyObject};
|
||||||
use std::os::raw::c_int;
|
use std::os::raw::c_int;
|
||||||
|
|
||||||
/// Operators for the __richcmp__ method
|
/// Operators for the __richcmp__ method
|
||||||
|
@ -134,50 +133,18 @@ pub trait PyObjectRichcmpProtocol<'p>: PyObjectProtocol<'p> {
|
||||||
type Result: IntoPyCallbackOutput<PyObject>;
|
type Result: IntoPyCallbackOutput<PyObject>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extension trait for proc-macro backend.
|
py_unary_func!(str, PyObjectStrProtocol, T::__str__);
|
||||||
|
py_unary_func!(repr, PyObjectReprProtocol, T::__repr__);
|
||||||
|
py_unary_func!(hash, PyObjectHashProtocol, T::__hash__, ffi::Py_hash_t);
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub trait PyBasicSlots {
|
pub unsafe extern "C" fn getattr<T>(
|
||||||
fn get_str() -> TypedSlot<ffi::reprfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyObjectStrProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_tp_str,
|
|
||||||
py_unary_func!(PyObjectStrProtocol, Self::__str__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_repr() -> TypedSlot<ffi::reprfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyObjectReprProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_tp_repr,
|
|
||||||
py_unary_func!(PyObjectReprProtocol, Self::__repr__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_hash() -> TypedSlot<ffi::hashfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyObjectHashProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_tp_hash,
|
|
||||||
py_unary_func!(PyObjectHashProtocol, Self::__hash__, ffi::Py_hash_t),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_getattr() -> TypedSlot<ffi::getattrofunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyObjectGetAttrProtocol<'p>,
|
|
||||||
{
|
|
||||||
unsafe extern "C" fn wrap<T>(
|
|
||||||
slf: *mut ffi::PyObject,
|
slf: *mut ffi::PyObject,
|
||||||
arg: *mut ffi::PyObject,
|
arg: *mut ffi::PyObject,
|
||||||
) -> *mut ffi::PyObject
|
) -> *mut ffi::PyObject
|
||||||
where
|
where
|
||||||
T: for<'p> PyObjectGetAttrProtocol<'p>,
|
T: for<'p> PyObjectGetAttrProtocol<'p>,
|
||||||
{
|
{
|
||||||
crate::callback_body!(py, {
|
crate::callback_body!(py, {
|
||||||
// Behave like python's __getattr__ (as opposed to __getattribute__) and check
|
// Behave like python's __getattr__ (as opposed to __getattribute__) and check
|
||||||
// for existing fields and methods first
|
// for existing fields and methods first
|
||||||
|
@ -193,91 +160,46 @@ pub trait PyBasicSlots {
|
||||||
let arg = py.from_borrowed_ptr::<PyAny>(arg);
|
let arg = py.from_borrowed_ptr::<PyAny>(arg);
|
||||||
call_ref!(slf, __getattr__, arg).convert(py)
|
call_ref!(slf, __getattr__, arg).convert(py)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
TypedSlot(ffi::Py_tp_getattro, wrap::<Self>)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_richcmp() -> TypedSlot<ffi::richcmpfunc>
|
#[doc(hidden)]
|
||||||
where
|
pub unsafe extern "C" fn richcmp<T>(
|
||||||
Self: for<'p> PyObjectRichcmpProtocol<'p>,
|
|
||||||
{
|
|
||||||
fn extract_op(op: c_int) -> PyResult<CompareOp> {
|
|
||||||
match op {
|
|
||||||
ffi::Py_LT => Ok(CompareOp::Lt),
|
|
||||||
ffi::Py_LE => Ok(CompareOp::Le),
|
|
||||||
ffi::Py_EQ => Ok(CompareOp::Eq),
|
|
||||||
ffi::Py_NE => Ok(CompareOp::Ne),
|
|
||||||
ffi::Py_GT => Ok(CompareOp::Gt),
|
|
||||||
ffi::Py_GE => Ok(CompareOp::Ge),
|
|
||||||
_ => Err(exceptions::PyValueError::new_err(
|
|
||||||
"tp_richcompare called with invalid comparison operator",
|
|
||||||
)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unsafe extern "C" fn wrap<T>(
|
|
||||||
slf: *mut ffi::PyObject,
|
slf: *mut ffi::PyObject,
|
||||||
arg: *mut ffi::PyObject,
|
arg: *mut ffi::PyObject,
|
||||||
op: c_int,
|
op: c_int,
|
||||||
) -> *mut ffi::PyObject
|
) -> *mut ffi::PyObject
|
||||||
where
|
where
|
||||||
T: for<'p> PyObjectRichcmpProtocol<'p>,
|
T: for<'p> PyObjectRichcmpProtocol<'p>,
|
||||||
{
|
{
|
||||||
crate::callback_body!(py, {
|
crate::callback_body!(py, {
|
||||||
let slf = py.from_borrowed_ptr::<crate::PyCell<T>>(slf);
|
let slf = py.from_borrowed_ptr::<crate::PyCell<T>>(slf);
|
||||||
let arg = extract_or_return_not_implemented!(py, arg);
|
let arg = extract_or_return_not_implemented!(py, arg);
|
||||||
let op = extract_op(op)?;
|
let op = match op {
|
||||||
|
ffi::Py_LT => CompareOp::Lt,
|
||||||
|
ffi::Py_LE => CompareOp::Le,
|
||||||
|
ffi::Py_EQ => CompareOp::Eq,
|
||||||
|
ffi::Py_NE => CompareOp::Ne,
|
||||||
|
ffi::Py_GT => CompareOp::Gt,
|
||||||
|
ffi::Py_GE => CompareOp::Ge,
|
||||||
|
_ => {
|
||||||
|
return Err(exceptions::PyValueError::new_err(
|
||||||
|
"tp_richcompare called with invalid comparison operator",
|
||||||
|
))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
slf.try_borrow()?.__richcmp__(arg, op).convert(py)
|
slf.try_borrow()?.__richcmp__(arg, op).convert(py)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
TypedSlot(ffi::Py_tp_richcompare, wrap::<Self>)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_setattr() -> TypedSlot<ffi::setattrofunc>
|
py_func_set!(setattr, PyObjectSetAttrProtocol, T::__setattr__);
|
||||||
where
|
py_func_del!(delattr, PyObjectDelAttrProtocol, T::__delattr__);
|
||||||
Self: for<'p> PyObjectSetAttrProtocol<'p>,
|
py_func_set_del!(
|
||||||
{
|
setdelattr,
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_tp_setattro,
|
|
||||||
py_func_set!(PyObjectSetAttrProtocol, Self::__setattr__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_delattr() -> TypedSlot<ffi::setattrofunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyObjectDelAttrProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_tp_setattro,
|
|
||||||
py_func_del!(PyObjectDelAttrProtocol, Self::__delattr__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_setdelattr() -> TypedSlot<ffi::setattrofunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyObjectSetAttrProtocol<'p> + for<'p> PyObjectDelAttrProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_tp_setattro,
|
|
||||||
py_func_set_del!(
|
|
||||||
PyObjectSetAttrProtocol,
|
PyObjectSetAttrProtocol,
|
||||||
PyObjectDelAttrProtocol,
|
PyObjectDelAttrProtocol,
|
||||||
Self,
|
Self,
|
||||||
__setattr__,
|
__setattr__,
|
||||||
__delattr__
|
__delattr__
|
||||||
),
|
);
|
||||||
)
|
py_unary_func!(bool, PyObjectBoolProtocol, T::__bool__, c_int);
|
||||||
}
|
|
||||||
|
|
||||||
fn get_bool() -> TypedSlot<ffi::inquiry>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyObjectBoolProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_bool,
|
|
||||||
py_unary_func!(PyObjectBoolProtocol, Self::__bool__, c_int),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'p, T> PyBasicSlots for T where T: PyObjectProtocol<'p> {}
|
|
||||||
|
|
|
@ -11,22 +11,18 @@ use std::os::raw::c_int;
|
||||||
/// Buffer protocol interface
|
/// Buffer protocol interface
|
||||||
///
|
///
|
||||||
/// For more information check [buffer protocol](https://docs.python.org/3/c-api/buffer.html)
|
/// For more information check [buffer protocol](https://docs.python.org/3/c-api/buffer.html)
|
||||||
/// c-api
|
/// c-api.
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
pub trait PyBufferProtocol<'p>: PyClass {
|
pub trait PyBufferProtocol<'p>: PyClass {
|
||||||
|
// No default implementations so that implementors of this trait provide both methods.
|
||||||
|
|
||||||
fn bf_getbuffer(slf: PyRefMut<Self>, view: *mut ffi::Py_buffer, flags: c_int) -> Self::Result
|
fn bf_getbuffer(slf: PyRefMut<Self>, view: *mut ffi::Py_buffer, flags: c_int) -> Self::Result
|
||||||
where
|
where
|
||||||
Self: PyBufferGetBufferProtocol<'p>,
|
Self: PyBufferGetBufferProtocol<'p>;
|
||||||
{
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn bf_releasebuffer(slf: PyRefMut<Self>, view: *mut ffi::Py_buffer) -> Self::Result
|
fn bf_releasebuffer(slf: PyRefMut<Self>, view: *mut ffi::Py_buffer) -> Self::Result
|
||||||
where
|
where
|
||||||
Self: PyBufferReleaseBufferProtocol<'p>,
|
Self: PyBufferReleaseBufferProtocol<'p>;
|
||||||
{
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait PyBufferGetBufferProtocol<'p>: PyBufferProtocol<'p> {
|
pub trait PyBufferGetBufferProtocol<'p>: PyBufferProtocol<'p> {
|
||||||
|
@ -37,46 +33,28 @@ pub trait PyBufferReleaseBufferProtocol<'p>: PyBufferProtocol<'p> {
|
||||||
type Result: IntoPyCallbackOutput<()>;
|
type Result: IntoPyCallbackOutput<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extension trait for proc-macro backend.
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub trait PyBufferSlots {
|
pub unsafe extern "C" fn getbuffer<T>(
|
||||||
fn get_getbuffer() -> ffi::getbufferproc
|
|
||||||
where
|
|
||||||
Self: for<'p> PyBufferGetBufferProtocol<'p>,
|
|
||||||
{
|
|
||||||
unsafe extern "C" fn wrap<T>(
|
|
||||||
slf: *mut ffi::PyObject,
|
slf: *mut ffi::PyObject,
|
||||||
arg1: *mut ffi::Py_buffer,
|
arg1: *mut ffi::Py_buffer,
|
||||||
arg2: c_int,
|
arg2: c_int,
|
||||||
) -> c_int
|
) -> c_int
|
||||||
where
|
where
|
||||||
T: for<'p> PyBufferGetBufferProtocol<'p>,
|
T: for<'p> PyBufferGetBufferProtocol<'p>,
|
||||||
{
|
{
|
||||||
crate::callback_body!(py, {
|
crate::callback_body!(py, {
|
||||||
let slf = py.from_borrowed_ptr::<PyCell<T>>(slf);
|
let slf = py.from_borrowed_ptr::<PyCell<T>>(slf);
|
||||||
T::bf_getbuffer(slf.try_borrow_mut()?, arg1, arg2).convert(py)
|
T::bf_getbuffer(slf.try_borrow_mut()?, arg1, arg2).convert(py)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
wrap::<Self>
|
#[doc(hidden)]
|
||||||
}
|
pub unsafe extern "C" fn releasebuffer<T>(slf: *mut ffi::PyObject, arg1: *mut ffi::Py_buffer)
|
||||||
|
where
|
||||||
fn get_releasebuffer() -> ffi::releasebufferproc
|
|
||||||
where
|
|
||||||
Self: for<'p> PyBufferReleaseBufferProtocol<'p>,
|
|
||||||
{
|
|
||||||
unsafe extern "C" fn wrap<T>(slf: *mut ffi::PyObject, arg1: *mut ffi::Py_buffer)
|
|
||||||
where
|
|
||||||
T: for<'p> PyBufferReleaseBufferProtocol<'p>,
|
T: for<'p> PyBufferReleaseBufferProtocol<'p>,
|
||||||
{
|
{
|
||||||
crate::callback_body!(py, {
|
crate::callback_body!(py, {
|
||||||
let slf = py.from_borrowed_ptr::<crate::PyCell<T>>(slf);
|
let slf = py.from_borrowed_ptr::<crate::PyCell<T>>(slf);
|
||||||
T::bf_releasebuffer(slf.try_borrow_mut()?, arg1).convert(py)
|
T::bf_releasebuffer(slf.try_borrow_mut()?, arg1).convert(py)
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
||||||
wrap::<Self>
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'p, T> PyBufferSlots for T where T: PyBufferProtocol<'p> {}
|
|
||||||
|
|
|
@ -5,10 +5,9 @@
|
||||||
//! [Python information](
|
//! [Python information](
|
||||||
//! https://docs.python.org/3/reference/datamodel.html#implementing-descriptors)
|
//! https://docs.python.org/3/reference/datamodel.html#implementing-descriptors)
|
||||||
|
|
||||||
use super::proto_methods::TypedSlot;
|
|
||||||
use crate::callback::IntoPyCallbackOutput;
|
use crate::callback::IntoPyCallbackOutput;
|
||||||
use crate::types::PyAny;
|
use crate::types::PyAny;
|
||||||
use crate::{ffi, FromPyObject, PyClass, PyObject};
|
use crate::{FromPyObject, PyClass, PyObject};
|
||||||
use std::os::raw::c_int;
|
use std::os::raw::c_int;
|
||||||
|
|
||||||
/// Descriptor interface
|
/// Descriptor interface
|
||||||
|
@ -71,28 +70,5 @@ pub trait PyDescrSetNameProtocol<'p>: PyDescrProtocol<'p> {
|
||||||
type Result: IntoPyCallbackOutput<()>;
|
type Result: IntoPyCallbackOutput<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extension trait for our proc-macro backend.
|
py_ternarys_func!(descr_get, PyDescrGetProtocol, Self::__get__);
|
||||||
#[doc(hidden)]
|
py_ternarys_func!(descr_set, PyDescrSetProtocol, Self::__set__, c_int);
|
||||||
pub trait PyDescrSlots {
|
|
||||||
fn get_descr_get() -> TypedSlot<ffi::descrgetfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyDescrGetProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_tp_descr_get,
|
|
||||||
py_ternarys_func!(PyDescrGetProtocol, Self::__get__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_descr_set() -> TypedSlot<ffi::descrsetfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyDescrSetProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_tp_descr_set,
|
|
||||||
py_ternarys_func!(PyDescrSetProtocol, Self::__set__, c_int),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'p, T> PyDescrSlots for T where T: PyDescrProtocol<'p> {}
|
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
//! Python GC support
|
//! Python GC support
|
||||||
//!
|
//!
|
||||||
|
|
||||||
use super::proto_methods::TypedSlot;
|
|
||||||
use crate::{ffi, AsPyPointer, PyCell, PyClass, Python};
|
use crate::{ffi, AsPyPointer, PyCell, PyClass, Python};
|
||||||
use std::os::raw::{c_int, c_void};
|
use std::os::raw::{c_int, c_void};
|
||||||
|
|
||||||
|
@ -19,21 +18,15 @@ pub trait PyGCProtocol<'p>: PyClass {
|
||||||
pub trait PyGCTraverseProtocol<'p>: PyGCProtocol<'p> {}
|
pub trait PyGCTraverseProtocol<'p>: PyGCProtocol<'p> {}
|
||||||
pub trait PyGCClearProtocol<'p>: PyGCProtocol<'p> {}
|
pub trait PyGCClearProtocol<'p>: PyGCProtocol<'p> {}
|
||||||
|
|
||||||
/// Extension trait for proc-macro backend.
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub trait PyGCSlots {
|
pub unsafe extern "C" fn traverse<T>(
|
||||||
fn get_traverse() -> TypedSlot<ffi::traverseproc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyGCTraverseProtocol<'p>,
|
|
||||||
{
|
|
||||||
unsafe extern "C" fn wrap<T>(
|
|
||||||
slf: *mut ffi::PyObject,
|
slf: *mut ffi::PyObject,
|
||||||
visit: ffi::visitproc,
|
visit: ffi::visitproc,
|
||||||
arg: *mut c_void,
|
arg: *mut c_void,
|
||||||
) -> c_int
|
) -> c_int
|
||||||
where
|
where
|
||||||
T: for<'p> PyGCTraverseProtocol<'p>,
|
T: for<'p> PyGCTraverseProtocol<'p>,
|
||||||
{
|
{
|
||||||
let pool = crate::GILPool::new();
|
let pool = crate::GILPool::new();
|
||||||
let py = pool.python();
|
let py = pool.python();
|
||||||
let slf = py.from_borrowed_ptr::<PyCell<T>>(slf);
|
let slf = py.from_borrowed_ptr::<PyCell<T>>(slf);
|
||||||
|
@ -52,32 +45,20 @@ pub trait PyGCSlots {
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TypedSlot(ffi::Py_tp_traverse, wrap::<Self>)
|
#[doc(hidden)]
|
||||||
}
|
pub unsafe extern "C" fn clear<T>(slf: *mut ffi::PyObject) -> c_int
|
||||||
|
where
|
||||||
fn get_clear() -> TypedSlot<ffi::inquiry>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyGCClearProtocol<'p>,
|
|
||||||
{
|
|
||||||
unsafe extern "C" fn wrap<T>(slf: *mut ffi::PyObject) -> c_int
|
|
||||||
where
|
|
||||||
T: for<'p> PyGCClearProtocol<'p>,
|
T: for<'p> PyGCClearProtocol<'p>,
|
||||||
{
|
{
|
||||||
let pool = crate::GILPool::new();
|
let pool = crate::GILPool::new();
|
||||||
let slf = pool.python().from_borrowed_ptr::<PyCell<T>>(slf);
|
let slf = pool.python().from_borrowed_ptr::<PyCell<T>>(slf);
|
||||||
|
|
||||||
slf.borrow_mut().__clear__();
|
slf.borrow_mut().__clear__();
|
||||||
0
|
0
|
||||||
}
|
|
||||||
|
|
||||||
TypedSlot(ffi::Py_tp_clear, wrap::<Self>)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'p, T> PyGCSlots for T where T: PyGCProtocol<'p> {}
|
|
||||||
|
|
||||||
/// Object visitor for GC.
|
/// Object visitor for GC.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct PyVisit<'p> {
|
pub struct PyVisit<'p> {
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
//! Python Iterator Interface.
|
//! Python Iterator Interface.
|
||||||
//! Trait and support implementation for implementing iterators
|
//! Trait and support implementation for implementing iterators
|
||||||
|
|
||||||
use super::proto_methods::TypedSlot;
|
|
||||||
use crate::callback::IntoPyCallbackOutput;
|
use crate::callback::IntoPyCallbackOutput;
|
||||||
use crate::derive_utils::TryFromPyCell;
|
use crate::derive_utils::TryFromPyCell;
|
||||||
use crate::err::PyResult;
|
use crate::err::PyResult;
|
||||||
|
@ -72,30 +71,8 @@ pub trait PyIterNextProtocol<'p>: PyIterProtocol<'p> {
|
||||||
type Result: IntoPyCallbackOutput<PyIterNextOutput>;
|
type Result: IntoPyCallbackOutput<PyIterNextOutput>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extension trait for proc-macro backend.
|
py_unarys_func!(iter, PyIterIterProtocol, Self::__iter__);
|
||||||
#[doc(hidden)]
|
py_unarys_func!(iternext, PyIterNextProtocol, Self::__next__);
|
||||||
pub trait PyIterSlots {
|
|
||||||
fn get_iter() -> TypedSlot<ffi::getiterfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyIterIterProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_tp_iter,
|
|
||||||
py_unarys_func!(PyIterIterProtocol, Self::__iter__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
fn get_iternext() -> TypedSlot<ffi::iternextfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyIterNextProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_tp_iternext,
|
|
||||||
py_unarys_func!(PyIterNextProtocol, Self::__next__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'p, T> PyIterSlots for T where T: PyIterProtocol<'p> {}
|
|
||||||
|
|
||||||
/// Output of `__next__` which can either `yield` the next value in the iteration, or
|
/// Output of `__next__` which can either `yield` the next value in the iteration, or
|
||||||
/// `return` a value to raise `StopIteration` in Python.
|
/// `return` a value to raise `StopIteration` in Python.
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
// Copyright (c) 2017-present PyO3 Project and Contributors
|
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||||
|
|
||||||
macro_rules! py_unary_func {
|
macro_rules! py_unary_func {
|
||||||
($trait: ident, $class:ident :: $f:ident, $call:ident, $ret_type: ty) => {{
|
($name:ident, $trait:ident, $class:ident :: $f:ident, $call:ident, $ret_type: ty) => {
|
||||||
unsafe extern "C" fn wrap<T>(slf: *mut $crate::ffi::PyObject) -> $ret_type
|
#[doc(hidden)]
|
||||||
|
pub unsafe extern "C" fn $name<T>(slf: *mut $crate::ffi::PyObject) -> $ret_type
|
||||||
where
|
where
|
||||||
T: for<'p> $trait<'p>,
|
T: for<'p> $trait<'p>,
|
||||||
{
|
{
|
||||||
|
@ -11,20 +12,28 @@ macro_rules! py_unary_func {
|
||||||
$call!(slf, $f).convert(py)
|
$call!(slf, $f).convert(py)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
wrap::<$class>
|
|
||||||
}};
|
|
||||||
// Use call_ref! by default
|
|
||||||
($trait:ident, $class:ident :: $f:ident, $ret_type:ty) => {
|
|
||||||
py_unary_func!($trait, $class::$f, call_ref, $ret_type);
|
|
||||||
};
|
};
|
||||||
($trait:ident, $class:ident :: $f:ident) => {
|
// Use call_ref! by default
|
||||||
py_unary_func!($trait, $class::$f, call_ref, *mut $crate::ffi::PyObject);
|
($name:ident, $trait:ident, $class:ident :: $f:ident, $ret_type:ty) => {
|
||||||
|
py_unary_func!($name, $trait, $class::$f, call_ref, $ret_type);
|
||||||
|
};
|
||||||
|
($name:ident, $trait:ident, $class:ident :: $f:ident) => {
|
||||||
|
py_unary_func!(
|
||||||
|
$name,
|
||||||
|
$trait,
|
||||||
|
$class::$f,
|
||||||
|
call_ref,
|
||||||
|
*mut $crate::ffi::PyObject
|
||||||
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! py_unarys_func {
|
macro_rules! py_unarys_func {
|
||||||
($trait:ident, $class:ident :: $f:ident) => {{
|
($name:ident, $trait:ident, $class:ident :: $f:ident) => {
|
||||||
unsafe extern "C" fn wrap<T>(slf: *mut $crate::ffi::PyObject) -> *mut $crate::ffi::PyObject
|
#[doc(hidden)]
|
||||||
|
pub unsafe extern "C" fn $name<T>(
|
||||||
|
slf: *mut $crate::ffi::PyObject,
|
||||||
|
) -> *mut $crate::ffi::PyObject
|
||||||
where
|
where
|
||||||
T: for<'p> $trait<'p>,
|
T: for<'p> $trait<'p>,
|
||||||
{
|
{
|
||||||
|
@ -37,20 +46,23 @@ macro_rules! py_unarys_func {
|
||||||
T::$f(borrow).convert(py)
|
T::$f(borrow).convert(py)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
wrap::<$class>
|
};
|
||||||
}};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! py_len_func {
|
macro_rules! py_len_func {
|
||||||
($trait:ident, $class:ident :: $f:ident) => {
|
($name:ident, $trait:ident, $class:ident :: $f:ident) => {
|
||||||
py_unary_func!($trait, $class::$f, $crate::ffi::Py_ssize_t)
|
py_unary_func!($name, $trait, $class::$f, $crate::ffi::Py_ssize_t);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! py_binary_func {
|
macro_rules! py_binary_func {
|
||||||
// Use call_ref! by default
|
// Use call_ref! by default
|
||||||
($trait:ident, $class:ident :: $f:ident, $return:ty, $call:ident) => {{
|
($name:ident, $trait:ident, $class:ident :: $f:ident, $return:ty, $call:ident) => {
|
||||||
unsafe extern "C" fn wrap<T>(slf: *mut ffi::PyObject, arg: *mut ffi::PyObject) -> $return
|
#[doc(hidden)]
|
||||||
|
pub unsafe extern "C" fn $name<T>(
|
||||||
|
slf: *mut ffi::PyObject,
|
||||||
|
arg: *mut ffi::PyObject,
|
||||||
|
) -> $return
|
||||||
where
|
where
|
||||||
T: for<'p> $trait<'p>,
|
T: for<'p> $trait<'p>,
|
||||||
{
|
{
|
||||||
|
@ -60,19 +72,19 @@ macro_rules! py_binary_func {
|
||||||
$call!(slf, $f, arg).convert(py)
|
$call!(slf, $f, arg).convert(py)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
wrap::<$class>
|
|
||||||
}};
|
|
||||||
($trait:ident, $class:ident :: $f:ident, $return:ty) => {
|
|
||||||
py_binary_func!($trait, $class::$f, $return, call_ref)
|
|
||||||
};
|
};
|
||||||
($trait:ident, $class:ident :: $f:ident) => {
|
($name:ident, $trait:ident, $class:ident :: $f:ident, $return:ty) => {
|
||||||
py_binary_func!($trait, $class::$f, *mut $crate::ffi::PyObject)
|
py_binary_func!($name, $trait, $class::$f, $return, call_ref);
|
||||||
|
};
|
||||||
|
($name:ident, $trait:ident, $class:ident :: $f:ident) => {
|
||||||
|
py_binary_func!($name, $trait, $class::$f, *mut $crate::ffi::PyObject);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! py_binary_num_func {
|
macro_rules! py_binary_num_func {
|
||||||
($trait:ident, $class:ident :: $f:ident) => {{
|
($name:ident, $trait:ident, $class:ident :: $f:ident) => {
|
||||||
unsafe extern "C" fn wrap<T>(
|
#[doc(hidden)]
|
||||||
|
pub unsafe extern "C" fn $name<T>(
|
||||||
lhs: *mut ffi::PyObject,
|
lhs: *mut ffi::PyObject,
|
||||||
rhs: *mut ffi::PyObject,
|
rhs: *mut ffi::PyObject,
|
||||||
) -> *mut $crate::ffi::PyObject
|
) -> *mut $crate::ffi::PyObject
|
||||||
|
@ -85,13 +97,13 @@ macro_rules! py_binary_num_func {
|
||||||
T::$f(lhs.extract()?, rhs).convert(py)
|
T::$f(lhs.extract()?, rhs).convert(py)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
wrap::<$class>
|
};
|
||||||
}};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! py_binary_reversed_num_func {
|
macro_rules! py_binary_reversed_num_func {
|
||||||
($trait:ident, $class:ident :: $f:ident) => {{
|
($name:ident, $trait:ident, $class:ident :: $f:ident) => {
|
||||||
unsafe extern "C" fn wrap<T>(
|
#[doc(hidden)]
|
||||||
|
pub unsafe extern "C" fn $name<T>(
|
||||||
lhs: *mut ffi::PyObject,
|
lhs: *mut ffi::PyObject,
|
||||||
rhs: *mut ffi::PyObject,
|
rhs: *mut ffi::PyObject,
|
||||||
) -> *mut $crate::ffi::PyObject
|
) -> *mut $crate::ffi::PyObject
|
||||||
|
@ -105,13 +117,13 @@ macro_rules! py_binary_reversed_num_func {
|
||||||
T::$f(&*slf.try_borrow()?, arg).convert(py)
|
T::$f(&*slf.try_borrow()?, arg).convert(py)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
wrap::<$class>
|
};
|
||||||
}};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! py_binary_fallback_num_func {
|
macro_rules! py_binary_fallback_num_func {
|
||||||
($class:ident, $lop_trait: ident :: $lop: ident, $rop_trait: ident :: $rop: ident) => {{
|
($name:ident, $class:ident, $lop_trait: ident :: $lop: ident, $rop_trait: ident :: $rop: ident) => {
|
||||||
unsafe extern "C" fn wrap<T>(
|
#[doc(hidden)]
|
||||||
|
pub unsafe extern "C" fn $name<T>(
|
||||||
lhs: *mut ffi::PyObject,
|
lhs: *mut ffi::PyObject,
|
||||||
rhs: *mut ffi::PyObject,
|
rhs: *mut ffi::PyObject,
|
||||||
) -> *mut $crate::ffi::PyObject
|
) -> *mut $crate::ffi::PyObject
|
||||||
|
@ -133,14 +145,14 @@ macro_rules! py_binary_fallback_num_func {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
wrap::<$class>
|
};
|
||||||
}};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE(kngwyu): This macro is used only for inplace operations, so I used call_mut here.
|
// NOTE(kngwyu): This macro is used only for inplace operations, so I used call_mut here.
|
||||||
macro_rules! py_binary_self_func {
|
macro_rules! py_binary_self_func {
|
||||||
($trait:ident, $class:ident :: $f:ident) => {{
|
($name:ident, $trait:ident, $class:ident :: $f:ident) => {
|
||||||
unsafe extern "C" fn wrap<T>(
|
#[doc(hidden)]
|
||||||
|
pub unsafe extern "C" fn $name<T>(
|
||||||
slf: *mut ffi::PyObject,
|
slf: *mut ffi::PyObject,
|
||||||
arg: *mut ffi::PyObject,
|
arg: *mut ffi::PyObject,
|
||||||
) -> *mut $crate::ffi::PyObject
|
) -> *mut $crate::ffi::PyObject
|
||||||
|
@ -155,17 +167,17 @@ macro_rules! py_binary_self_func {
|
||||||
Ok::<_, $crate::err::PyErr>(slf)
|
Ok::<_, $crate::err::PyErr>(slf)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
wrap::<$class>
|
};
|
||||||
}};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! py_ssizearg_func {
|
macro_rules! py_ssizearg_func {
|
||||||
// Use call_ref! by default
|
// Use call_ref! by default
|
||||||
($trait:ident, $class:ident :: $f:ident) => {
|
($name:ident, $trait:ident, $class:ident :: $f:ident) => {
|
||||||
py_ssizearg_func!($trait, $class::$f, call_ref)
|
py_ssizearg_func!($name, $trait, $class::$f, call_ref);
|
||||||
};
|
};
|
||||||
($trait:ident, $class:ident :: $f:ident, $call:ident) => {{
|
($name:ident, $trait:ident, $class:ident :: $f:ident, $call:ident) => {
|
||||||
unsafe extern "C" fn wrap<T>(
|
#[doc(hidden)]
|
||||||
|
pub unsafe extern "C" fn $name<T>(
|
||||||
slf: *mut ffi::PyObject,
|
slf: *mut ffi::PyObject,
|
||||||
arg: $crate::ffi::Py_ssize_t,
|
arg: $crate::ffi::Py_ssize_t,
|
||||||
) -> *mut $crate::ffi::PyObject
|
) -> *mut $crate::ffi::PyObject
|
||||||
|
@ -177,13 +189,13 @@ macro_rules! py_ssizearg_func {
|
||||||
$call!(slf, $f; arg.into()).convert(py)
|
$call!(slf, $f; arg.into()).convert(py)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
wrap::<$class>
|
};
|
||||||
}};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! py_ternarys_func {
|
macro_rules! py_ternarys_func {
|
||||||
($trait:ident, $class:ident :: $f:ident, $return_type:ty) => {{
|
($name:ident, $trait:ident, $class:ident :: $f:ident, $return_type:ty) => {
|
||||||
unsafe extern "C" fn wrap<T>(
|
#[doc(hidden)]
|
||||||
|
pub unsafe extern "C" fn $name<T>(
|
||||||
slf: *mut $crate::ffi::PyObject,
|
slf: *mut $crate::ffi::PyObject,
|
||||||
arg1: *mut $crate::ffi::PyObject,
|
arg1: *mut $crate::ffi::PyObject,
|
||||||
arg2: *mut $crate::ffi::PyObject,
|
arg2: *mut $crate::ffi::PyObject,
|
||||||
|
@ -206,17 +218,16 @@ macro_rules! py_ternarys_func {
|
||||||
T::$f(slf, arg1, arg2).convert(py)
|
T::$f(slf, arg1, arg2).convert(py)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
};
|
||||||
wrap::<$class>
|
($name:ident, $trait:ident, $class:ident :: $f:ident) => {
|
||||||
}};
|
py_ternarys_func!($name, $trait, $class::$f, *mut $crate::ffi::PyObject);
|
||||||
($trait:ident, $class:ident :: $f:ident) => {
|
|
||||||
py_ternarys_func!($trait, $class::$f, *mut $crate::ffi::PyObject);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! py_func_set {
|
macro_rules! py_func_set {
|
||||||
($trait_name:ident, $class:ident :: $fn_set:ident) => {{
|
($name:ident, $trait_name:ident, $class:ident :: $fn_set:ident) => {
|
||||||
unsafe extern "C" fn wrap<T>(
|
#[doc(hidden)]
|
||||||
|
pub unsafe extern "C" fn $name<T>(
|
||||||
slf: *mut $crate::ffi::PyObject,
|
slf: *mut $crate::ffi::PyObject,
|
||||||
name: *mut $crate::ffi::PyObject,
|
name: *mut $crate::ffi::PyObject,
|
||||||
value: *mut $crate::ffi::PyObject,
|
value: *mut $crate::ffi::PyObject,
|
||||||
|
@ -239,14 +250,13 @@ macro_rules! py_func_set {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
};
|
||||||
wrap::<$class>
|
|
||||||
}};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! py_func_del {
|
macro_rules! py_func_del {
|
||||||
($trait_name:ident, $class:ident :: $fn_del:ident) => {{
|
($name:ident, $trait_name:ident, $class:ident :: $fn_del:ident) => {
|
||||||
unsafe extern "C" fn wrap<T>(
|
#[doc(hidden)]
|
||||||
|
pub unsafe extern "C" fn $name<T>(
|
||||||
slf: *mut $crate::ffi::PyObject,
|
slf: *mut $crate::ffi::PyObject,
|
||||||
name: *mut $crate::ffi::PyObject,
|
name: *mut $crate::ffi::PyObject,
|
||||||
value: *mut $crate::ffi::PyObject,
|
value: *mut $crate::ffi::PyObject,
|
||||||
|
@ -268,14 +278,13 @@ macro_rules! py_func_del {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
};
|
||||||
wrap::<$class>
|
|
||||||
}};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! py_func_set_del {
|
macro_rules! py_func_set_del {
|
||||||
($trait1:ident, $trait2:ident, $class:ident, $fn_set:ident, $fn_del:ident) => {{
|
($name:ident, $trait1:ident, $trait2:ident, $class:ident, $fn_set:ident, $fn_del:ident) => {
|
||||||
unsafe extern "C" fn wrap<T>(
|
#[doc(hidden)]
|
||||||
|
pub unsafe extern "C" fn $name<T>(
|
||||||
slf: *mut $crate::ffi::PyObject,
|
slf: *mut $crate::ffi::PyObject,
|
||||||
name: *mut $crate::ffi::PyObject,
|
name: *mut $crate::ffi::PyObject,
|
||||||
value: *mut $crate::ffi::PyObject,
|
value: *mut $crate::ffi::PyObject,
|
||||||
|
@ -295,8 +304,7 @@ macro_rules! py_func_set_del {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
wrap::<$class>
|
};
|
||||||
}};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! extract_or_return_not_implemented {
|
macro_rules! extract_or_return_not_implemented {
|
||||||
|
|
|
@ -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 super::proto_methods::TypedSlot;
|
|
||||||
use crate::callback::IntoPyCallbackOutput;
|
use crate::callback::IntoPyCallbackOutput;
|
||||||
use crate::{exceptions, ffi, FromPyObject, PyClass, PyObject};
|
use crate::{exceptions, ffi, FromPyObject, PyClass, PyObject};
|
||||||
|
|
||||||
|
@ -73,64 +72,15 @@ pub trait PyMappingReversedProtocol<'p>: PyMappingProtocol<'p> {
|
||||||
type Result: IntoPyCallbackOutput<PyObject>;
|
type Result: IntoPyCallbackOutput<PyObject>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extension trait for proc-macro backend.
|
py_len_func!(len, PyMappingLenProtocol, Self::__len__);
|
||||||
#[doc(hidden)]
|
py_binary_func!(getitem, PyMappingGetItemProtocol, Self::__getitem__);
|
||||||
pub trait PyMappingSlots {
|
py_func_set!(setitem, PyMappingSetItemProtocol, Self::__setitem__);
|
||||||
fn get_len() -> TypedSlot<ffi::lenfunc>
|
py_func_del!(delitem, PyMappingDelItemProtocol, Self::__delitem__);
|
||||||
where
|
py_func_set_del!(
|
||||||
Self: for<'p> PyMappingLenProtocol<'p>,
|
setdelitem,
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_mp_length,
|
|
||||||
py_len_func!(PyMappingLenProtocol, Self::__len__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_getitem() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyMappingGetItemProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_mp_subscript,
|
|
||||||
py_binary_func!(PyMappingGetItemProtocol, Self::__getitem__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_setitem() -> TypedSlot<ffi::objobjargproc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyMappingSetItemProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_mp_ass_subscript,
|
|
||||||
py_func_set!(PyMappingSetItemProtocol, Self::__setitem__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_delitem() -> TypedSlot<ffi::objobjargproc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyMappingDelItemProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_mp_ass_subscript,
|
|
||||||
py_func_del!(PyMappingDelItemProtocol, Self::__delitem__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_setdelitem() -> TypedSlot<ffi::objobjargproc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyMappingSetItemProtocol<'p> + for<'p> PyMappingDelItemProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_mp_ass_subscript,
|
|
||||||
py_func_set_del!(
|
|
||||||
PyMappingSetItemProtocol,
|
PyMappingSetItemProtocol,
|
||||||
PyMappingDelItemProtocol,
|
PyMappingDelItemProtocol,
|
||||||
Self,
|
Self,
|
||||||
__setitem__,
|
__setitem__,
|
||||||
__delitem__
|
__delitem__
|
||||||
),
|
);
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'p, T> PyMappingSlots for T where T: PyMappingProtocol<'p> {}
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ pub mod mapping;
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub mod methods;
|
pub mod methods;
|
||||||
pub mod number;
|
pub mod number;
|
||||||
|
#[doc(hidden)]
|
||||||
pub mod proto_methods;
|
pub mod proto_methods;
|
||||||
pub mod pyasync;
|
pub mod pyasync;
|
||||||
pub mod sequence;
|
pub mod sequence;
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
//! Python Number Interface
|
//! Python Number Interface
|
||||||
//! Trait and support implementation for implementing number protocol
|
//! Trait and support implementation for implementing number protocol
|
||||||
use super::proto_methods::TypedSlot;
|
|
||||||
use crate::callback::IntoPyCallbackOutput;
|
use crate::callback::IntoPyCallbackOutput;
|
||||||
use crate::err::PyErr;
|
use crate::err::PyErr;
|
||||||
use crate::{ffi, FromPyObject, PyClass, PyObject};
|
use crate::{ffi, FromPyObject, PyClass, PyObject};
|
||||||
|
@ -579,167 +578,49 @@ pub trait PyNumberIndexProtocol<'p>: PyNumberProtocol<'p> {
|
||||||
type Result: IntoPyCallbackOutput<PyObject>;
|
type Result: IntoPyCallbackOutput<PyObject>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extension trait for proc-macro backend.
|
py_binary_fallback_num_func!(
|
||||||
#[doc(hidden)]
|
add_radd,
|
||||||
pub trait PyNumberSlots {
|
T,
|
||||||
fn get_add_radd() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberAddProtocol<'p> + for<'p> PyNumberRAddProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_add,
|
|
||||||
py_binary_fallback_num_func!(
|
|
||||||
Self,
|
|
||||||
PyNumberAddProtocol::__add__,
|
PyNumberAddProtocol::__add__,
|
||||||
PyNumberRAddProtocol::__radd__
|
PyNumberRAddProtocol::__radd__
|
||||||
),
|
);
|
||||||
)
|
py_binary_num_func!(add, PyNumberAddProtocol, T::__add__);
|
||||||
}
|
py_binary_reversed_num_func!(radd, PyNumberRAddProtocol, T::__radd__);
|
||||||
|
py_binary_fallback_num_func!(
|
||||||
fn get_add() -> TypedSlot<ffi::binaryfunc>
|
sub_rsub,
|
||||||
where
|
T,
|
||||||
Self: for<'p> PyNumberAddProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_add,
|
|
||||||
py_binary_num_func!(PyNumberAddProtocol, Self::__add__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_radd() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberRAddProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_add,
|
|
||||||
py_binary_reversed_num_func!(PyNumberRAddProtocol, Self::__radd__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_sub_rsub() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberSubProtocol<'p> + for<'p> PyNumberRSubProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_subtract,
|
|
||||||
py_binary_fallback_num_func!(
|
|
||||||
Self,
|
|
||||||
PyNumberSubProtocol::__sub__,
|
PyNumberSubProtocol::__sub__,
|
||||||
PyNumberRSubProtocol::__rsub__
|
PyNumberRSubProtocol::__rsub__
|
||||||
),
|
);
|
||||||
)
|
py_binary_num_func!(sub, PyNumberSubProtocol, T::__sub__);
|
||||||
}
|
py_binary_reversed_num_func!(rsub, PyNumberRSubProtocol, T::__rsub__);
|
||||||
|
py_binary_fallback_num_func!(
|
||||||
fn get_sub() -> TypedSlot<ffi::binaryfunc>
|
mul_rmul,
|
||||||
where
|
T,
|
||||||
Self: for<'p> PyNumberSubProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_subtract,
|
|
||||||
py_binary_num_func!(PyNumberSubProtocol, Self::__sub__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_rsub() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberRSubProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_subtract,
|
|
||||||
py_binary_reversed_num_func!(PyNumberRSubProtocol, Self::__rsub__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_mul_rmul() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberMulProtocol<'p> + for<'p> PyNumberRMulProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_multiply,
|
|
||||||
py_binary_fallback_num_func!(
|
|
||||||
Self,
|
|
||||||
PyNumberMulProtocol::__mul__,
|
PyNumberMulProtocol::__mul__,
|
||||||
PyNumberRMulProtocol::__rmul__
|
PyNumberRMulProtocol::__rmul__
|
||||||
),
|
);
|
||||||
)
|
py_binary_num_func!(mul, PyNumberMulProtocol, T::__mul__);
|
||||||
}
|
py_binary_reversed_num_func!(rmul, PyNumberRMulProtocol, T::__rmul__);
|
||||||
|
py_binary_num_func!(mod_, PyNumberModProtocol, T::__mod__);
|
||||||
fn get_mul() -> TypedSlot<ffi::binaryfunc>
|
py_binary_fallback_num_func!(
|
||||||
where
|
divmod_rdivmod,
|
||||||
Self: for<'p> PyNumberMulProtocol<'p>,
|
T,
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_multiply,
|
|
||||||
py_binary_num_func!(PyNumberMulProtocol, Self::__mul__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_rmul() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberRMulProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_multiply,
|
|
||||||
py_binary_reversed_num_func!(PyNumberRMulProtocol, Self::__rmul__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_mod() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberModProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_remainder,
|
|
||||||
py_binary_num_func!(PyNumberModProtocol, Self::__mod__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_divmod_rdivmod() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberDivmodProtocol<'p> + for<'p> PyNumberRDivmodProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_divmod,
|
|
||||||
py_binary_fallback_num_func!(
|
|
||||||
Self,
|
|
||||||
PyNumberDivmodProtocol::__divmod__,
|
PyNumberDivmodProtocol::__divmod__,
|
||||||
PyNumberRDivmodProtocol::__rdivmod__
|
PyNumberRDivmodProtocol::__rdivmod__
|
||||||
),
|
);
|
||||||
)
|
py_binary_num_func!(divmod, PyNumberDivmodProtocol, T::__divmod__);
|
||||||
}
|
py_binary_reversed_num_func!(rdivmod, PyNumberRDivmodProtocol, T::__rdivmod__);
|
||||||
|
|
||||||
fn get_divmod() -> TypedSlot<ffi::binaryfunc>
|
#[doc(hidden)]
|
||||||
where
|
pub unsafe extern "C" fn pow_rpow<T>(
|
||||||
Self: for<'p> PyNumberDivmodProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_divmod,
|
|
||||||
py_binary_num_func!(PyNumberDivmodProtocol, Self::__divmod__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_rdivmod() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberRDivmodProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_divmod,
|
|
||||||
py_binary_reversed_num_func!(PyNumberRDivmodProtocol, Self::__rdivmod__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_pow_rpow() -> TypedSlot<ffi::ternaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberPowProtocol<'p> + for<'p> PyNumberRPowProtocol<'p>,
|
|
||||||
{
|
|
||||||
unsafe extern "C" fn wrap_pow_and_rpow<T>(
|
|
||||||
lhs: *mut ffi::PyObject,
|
lhs: *mut ffi::PyObject,
|
||||||
rhs: *mut ffi::PyObject,
|
rhs: *mut ffi::PyObject,
|
||||||
modulo: *mut ffi::PyObject,
|
modulo: *mut ffi::PyObject,
|
||||||
) -> *mut ffi::PyObject
|
) -> *mut ffi::PyObject
|
||||||
where
|
where
|
||||||
T: for<'p> PyNumberPowProtocol<'p> + for<'p> PyNumberRPowProtocol<'p>,
|
T: for<'p> PyNumberPowProtocol<'p> + for<'p> PyNumberRPowProtocol<'p>,
|
||||||
{
|
{
|
||||||
crate::callback_body!(py, {
|
crate::callback_body!(py, {
|
||||||
let lhs = py.from_borrowed_ptr::<crate::PyAny>(lhs);
|
let lhs = py.from_borrowed_ptr::<crate::PyAny>(lhs);
|
||||||
let rhs = py.from_borrowed_ptr::<crate::PyAny>(rhs);
|
let rhs = py.from_borrowed_ptr::<crate::PyAny>(rhs);
|
||||||
|
@ -756,341 +637,104 @@ pub trait PyNumberSlots {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
TypedSlot(ffi::Py_nb_power, wrap_pow_and_rpow::<Self>)
|
#[doc(hidden)]
|
||||||
}
|
pub unsafe extern "C" fn pow<T>(
|
||||||
|
|
||||||
fn get_pow() -> TypedSlot<ffi::ternaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberPowProtocol<'p>,
|
|
||||||
{
|
|
||||||
unsafe extern "C" fn wrap_pow<T>(
|
|
||||||
lhs: *mut ffi::PyObject,
|
lhs: *mut ffi::PyObject,
|
||||||
rhs: *mut ffi::PyObject,
|
rhs: *mut ffi::PyObject,
|
||||||
modulo: *mut ffi::PyObject,
|
modulo: *mut ffi::PyObject,
|
||||||
) -> *mut ffi::PyObject
|
) -> *mut ffi::PyObject
|
||||||
where
|
where
|
||||||
T: for<'p> PyNumberPowProtocol<'p>,
|
T: for<'p> PyNumberPowProtocol<'p>,
|
||||||
{
|
{
|
||||||
crate::callback_body!(py, {
|
crate::callback_body!(py, {
|
||||||
let lhs = extract_or_return_not_implemented!(py, lhs);
|
let lhs = extract_or_return_not_implemented!(py, lhs);
|
||||||
let rhs = extract_or_return_not_implemented!(py, rhs);
|
let rhs = extract_or_return_not_implemented!(py, rhs);
|
||||||
let modulo = extract_or_return_not_implemented!(py, modulo);
|
let modulo = extract_or_return_not_implemented!(py, modulo);
|
||||||
T::__pow__(lhs, rhs, modulo).convert(py)
|
T::__pow__(lhs, rhs, modulo).convert(py)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
TypedSlot(ffi::Py_nb_power, wrap_pow::<Self>)
|
#[doc(hidden)]
|
||||||
}
|
pub unsafe extern "C" fn rpow<T>(
|
||||||
|
|
||||||
fn get_rpow() -> TypedSlot<ffi::ternaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberRPowProtocol<'p>,
|
|
||||||
{
|
|
||||||
unsafe extern "C" fn wrap_rpow<T>(
|
|
||||||
arg: *mut ffi::PyObject,
|
arg: *mut ffi::PyObject,
|
||||||
slf: *mut ffi::PyObject,
|
slf: *mut ffi::PyObject,
|
||||||
modulo: *mut ffi::PyObject,
|
modulo: *mut ffi::PyObject,
|
||||||
) -> *mut ffi::PyObject
|
) -> *mut ffi::PyObject
|
||||||
where
|
where
|
||||||
T: for<'p> PyNumberRPowProtocol<'p>,
|
T: for<'p> PyNumberRPowProtocol<'p>,
|
||||||
{
|
{
|
||||||
crate::callback_body!(py, {
|
crate::callback_body!(py, {
|
||||||
let slf: &crate::PyCell<T> = extract_or_return_not_implemented!(py, slf);
|
let slf: &crate::PyCell<T> = extract_or_return_not_implemented!(py, slf);
|
||||||
let arg = extract_or_return_not_implemented!(py, arg);
|
let arg = extract_or_return_not_implemented!(py, arg);
|
||||||
let modulo = extract_or_return_not_implemented!(py, modulo);
|
let modulo = extract_or_return_not_implemented!(py, modulo);
|
||||||
slf.try_borrow()?.__rpow__(arg, modulo).convert(py)
|
slf.try_borrow()?.__rpow__(arg, modulo).convert(py)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
TypedSlot(ffi::Py_nb_power, wrap_rpow::<Self>)
|
py_unary_func!(neg, PyNumberNegProtocol, T::__neg__);
|
||||||
}
|
py_unary_func!(pos, PyNumberPosProtocol, T::__pos__);
|
||||||
|
py_unary_func!(abs, PyNumberAbsProtocol, T::__abs__);
|
||||||
fn get_neg() -> TypedSlot<ffi::unaryfunc>
|
py_unary_func!(invert, PyNumberInvertProtocol, T::__invert__);
|
||||||
where
|
py_binary_fallback_num_func!(
|
||||||
Self: for<'p> PyNumberNegProtocol<'p>,
|
lshift_rlshift,
|
||||||
{
|
T,
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_negative,
|
|
||||||
py_unary_func!(PyNumberNegProtocol, Self::__neg__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_pos() -> TypedSlot<ffi::unaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberPosProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_positive,
|
|
||||||
py_unary_func!(PyNumberPosProtocol, Self::__pos__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_abs() -> TypedSlot<ffi::unaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberAbsProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_absolute,
|
|
||||||
py_unary_func!(PyNumberAbsProtocol, Self::__abs__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_invert() -> TypedSlot<ffi::unaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberInvertProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_invert,
|
|
||||||
py_unary_func!(PyNumberInvertProtocol, Self::__invert__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_lshift_rlshift() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberLShiftProtocol<'p> + for<'p> PyNumberRLShiftProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_lshift,
|
|
||||||
py_binary_fallback_num_func!(
|
|
||||||
Self,
|
|
||||||
PyNumberLShiftProtocol::__lshift__,
|
PyNumberLShiftProtocol::__lshift__,
|
||||||
PyNumberRLShiftProtocol::__rlshift__
|
PyNumberRLShiftProtocol::__rlshift__
|
||||||
),
|
);
|
||||||
)
|
py_binary_num_func!(lshift, PyNumberLShiftProtocol, T::__lshift__);
|
||||||
}
|
py_binary_reversed_num_func!(rlshift, PyNumberRLShiftProtocol, T::__rlshift__);
|
||||||
|
py_binary_fallback_num_func!(
|
||||||
fn get_lshift() -> TypedSlot<ffi::binaryfunc>
|
rshift_rrshift,
|
||||||
where
|
T,
|
||||||
Self: for<'p> PyNumberLShiftProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_lshift,
|
|
||||||
py_binary_num_func!(PyNumberLShiftProtocol, Self::__lshift__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_rlshift() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberRLShiftProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_lshift,
|
|
||||||
py_binary_reversed_num_func!(PyNumberRLShiftProtocol, Self::__rlshift__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_rshift_rrshift() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberRShiftProtocol<'p> + for<'p> PyNumberRRShiftProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_rshift,
|
|
||||||
py_binary_fallback_num_func!(
|
|
||||||
Self,
|
|
||||||
PyNumberRShiftProtocol::__rshift__,
|
PyNumberRShiftProtocol::__rshift__,
|
||||||
PyNumberRRShiftProtocol::__rrshift__
|
PyNumberRRShiftProtocol::__rrshift__
|
||||||
),
|
);
|
||||||
)
|
py_binary_num_func!(rshift, PyNumberRShiftProtocol, T::__rshift__);
|
||||||
}
|
py_binary_reversed_num_func!(rrshift, PyNumberRRShiftProtocol, T::__rrshift__);
|
||||||
|
py_binary_fallback_num_func!(
|
||||||
fn get_rshift() -> TypedSlot<ffi::binaryfunc>
|
and_rand,
|
||||||
where
|
T,
|
||||||
Self: for<'p> PyNumberRShiftProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_rshift,
|
|
||||||
py_binary_num_func!(PyNumberRShiftProtocol, Self::__rshift__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_rrshift() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberRRShiftProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_rshift,
|
|
||||||
py_binary_reversed_num_func!(PyNumberRRShiftProtocol, Self::__rrshift__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_and_rand() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberAndProtocol<'p> + for<'p> PyNumberRAndProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_and,
|
|
||||||
py_binary_fallback_num_func!(
|
|
||||||
Self,
|
|
||||||
PyNumberAndProtocol::__and__,
|
PyNumberAndProtocol::__and__,
|
||||||
PyNumberRAndProtocol::__rand__
|
PyNumberRAndProtocol::__rand__
|
||||||
),
|
);
|
||||||
)
|
py_binary_num_func!(and, PyNumberAndProtocol, T::__and__);
|
||||||
}
|
py_binary_reversed_num_func!(rand, PyNumberRAndProtocol, T::__rand__);
|
||||||
|
py_binary_fallback_num_func!(
|
||||||
fn get_and() -> TypedSlot<ffi::binaryfunc>
|
xor_rxor,
|
||||||
where
|
T,
|
||||||
Self: for<'p> PyNumberAndProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_and,
|
|
||||||
py_binary_num_func!(PyNumberAndProtocol, Self::__and__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_rand() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberRAndProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_and,
|
|
||||||
py_binary_reversed_num_func!(PyNumberRAndProtocol, Self::__rand__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_xor_rxor() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberXorProtocol<'p> + for<'p> PyNumberRXorProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_xor,
|
|
||||||
py_binary_fallback_num_func!(
|
|
||||||
Self,
|
|
||||||
PyNumberXorProtocol::__xor__,
|
PyNumberXorProtocol::__xor__,
|
||||||
PyNumberRXorProtocol::__rxor__
|
PyNumberRXorProtocol::__rxor__
|
||||||
),
|
);
|
||||||
)
|
py_binary_num_func!(xor, PyNumberXorProtocol, T::__xor__);
|
||||||
}
|
py_binary_reversed_num_func!(rxor, PyNumberRXorProtocol, T::__rxor__);
|
||||||
|
py_binary_fallback_num_func!(
|
||||||
fn get_xor() -> TypedSlot<ffi::binaryfunc>
|
or_ror,
|
||||||
where
|
T,
|
||||||
Self: for<'p> PyNumberXorProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_xor,
|
|
||||||
py_binary_num_func!(PyNumberXorProtocol, Self::__xor__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_rxor() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberRXorProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_xor,
|
|
||||||
py_binary_reversed_num_func!(PyNumberRXorProtocol, Self::__rxor__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_or_ror() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberOrProtocol<'p> + for<'p> PyNumberROrProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_or,
|
|
||||||
py_binary_fallback_num_func!(
|
|
||||||
Self,
|
|
||||||
PyNumberOrProtocol::__or__,
|
PyNumberOrProtocol::__or__,
|
||||||
PyNumberROrProtocol::__ror__
|
PyNumberROrProtocol::__ror__
|
||||||
),
|
);
|
||||||
)
|
py_binary_num_func!(or, PyNumberOrProtocol, T::__or__);
|
||||||
}
|
py_binary_reversed_num_func!(ror, PyNumberROrProtocol, T::__ror__);
|
||||||
|
py_unary_func!(int, PyNumberIntProtocol, T::__int__);
|
||||||
|
py_unary_func!(float, PyNumberFloatProtocol, T::__float__);
|
||||||
|
py_binary_self_func!(iadd, PyNumberIAddProtocol, T::__iadd__);
|
||||||
|
py_binary_self_func!(isub, PyNumberISubProtocol, T::__isub__);
|
||||||
|
py_binary_self_func!(imul, PyNumberIMulProtocol, T::__imul__);
|
||||||
|
py_binary_self_func!(imod, PyNumberIModProtocol, T::__imod__);
|
||||||
|
|
||||||
fn get_or() -> TypedSlot<ffi::binaryfunc>
|
#[doc(hidden)]
|
||||||
where
|
pub unsafe extern "C" fn ipow<T>(
|
||||||
Self: for<'p> PyNumberOrProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_or,
|
|
||||||
py_binary_num_func!(PyNumberOrProtocol, Self::__or__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_ror() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberROrProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_or,
|
|
||||||
py_binary_reversed_num_func!(PyNumberROrProtocol, Self::__ror__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_int() -> TypedSlot<ffi::unaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberIntProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_int,
|
|
||||||
py_unary_func!(PyNumberIntProtocol, Self::__int__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_float() -> TypedSlot<ffi::unaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberFloatProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_float,
|
|
||||||
py_unary_func!(PyNumberFloatProtocol, Self::__float__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_iadd() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberIAddProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_inplace_add,
|
|
||||||
py_binary_self_func!(PyNumberIAddProtocol, Self::__iadd__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_isub() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberISubProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_inplace_subtract,
|
|
||||||
py_binary_self_func!(PyNumberISubProtocol, Self::__isub__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_imul() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberIMulProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_inplace_multiply,
|
|
||||||
py_binary_self_func!(PyNumberIMulProtocol, Self::__imul__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_imod() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberIModProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_inplace_remainder,
|
|
||||||
py_binary_self_func!(PyNumberIModProtocol, Self::__imod__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_ipow() -> TypedSlot<ffi::ternaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberIPowProtocol<'p>,
|
|
||||||
{
|
|
||||||
// NOTE: Somehow __ipow__ causes SIGSEGV in Python < 3.8 when we extract,
|
|
||||||
// so we ignore it. It's the same as what CPython does.
|
|
||||||
unsafe extern "C" fn wrap_ipow<T>(
|
|
||||||
slf: *mut ffi::PyObject,
|
slf: *mut ffi::PyObject,
|
||||||
other: *mut ffi::PyObject,
|
other: *mut ffi::PyObject,
|
||||||
_modulo: *mut ffi::PyObject,
|
_modulo: *mut ffi::PyObject,
|
||||||
) -> *mut ffi::PyObject
|
) -> *mut ffi::PyObject
|
||||||
where
|
where
|
||||||
T: for<'p> PyNumberIPowProtocol<'p>,
|
T: for<'p> PyNumberIPowProtocol<'p>,
|
||||||
{
|
{
|
||||||
|
// NOTE: Somehow __ipow__ causes SIGSEGV in Python < 3.8 when we extract,
|
||||||
|
// so we ignore it. It's the same as what CPython does.
|
||||||
crate::callback_body!(py, {
|
crate::callback_body!(py, {
|
||||||
let slf_cell = py.from_borrowed_ptr::<crate::PyCell<T>>(slf);
|
let slf_cell = py.from_borrowed_ptr::<crate::PyCell<T>>(slf);
|
||||||
let other = py.from_borrowed_ptr::<crate::PyAny>(other);
|
let other = py.from_borrowed_ptr::<crate::PyAny>(other);
|
||||||
|
@ -1098,202 +742,38 @@ pub trait PyNumberSlots {
|
||||||
ffi::Py_INCREF(slf);
|
ffi::Py_INCREF(slf);
|
||||||
Ok::<_, PyErr>(slf)
|
Ok::<_, PyErr>(slf)
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
||||||
TypedSlot(ffi::Py_nb_inplace_power, wrap_ipow::<Self>)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_ilshift() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberILShiftProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_inplace_lshift,
|
|
||||||
py_binary_self_func!(PyNumberILShiftProtocol, Self::__ilshift__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_irshift() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberIRShiftProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_inplace_rshift,
|
|
||||||
py_binary_self_func!(PyNumberIRShiftProtocol, Self::__irshift__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_iand() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberIAndProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_inplace_and,
|
|
||||||
py_binary_self_func!(PyNumberIAndProtocol, Self::__iand__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_ixor() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberIXorProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_inplace_xor,
|
|
||||||
py_binary_self_func!(PyNumberIXorProtocol, Self::__ixor__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_ior() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberIOrProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_inplace_or,
|
|
||||||
py_binary_self_func!(PyNumberIOrProtocol, Self::__ior__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_floordiv_rfloordiv() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberFloordivProtocol<'p> + for<'p> PyNumberRFloordivProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_floor_divide,
|
|
||||||
py_binary_fallback_num_func!(
|
|
||||||
Self,
|
|
||||||
PyNumberFloordivProtocol::__floordiv__,
|
|
||||||
PyNumberRFloordivProtocol::__rfloordiv__
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_floordiv() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberFloordivProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_floor_divide,
|
|
||||||
py_binary_num_func!(PyNumberFloordivProtocol, Self::__floordiv__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_rfloordiv() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberRFloordivProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_floor_divide,
|
|
||||||
py_binary_reversed_num_func!(PyNumberRFloordivProtocol, Self::__rfloordiv__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_truediv_rtruediv() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberTruedivProtocol<'p> + for<'p> PyNumberRTruedivProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_true_divide,
|
|
||||||
py_binary_fallback_num_func!(
|
|
||||||
Self,
|
|
||||||
PyNumberTruedivProtocol::__truediv__,
|
|
||||||
PyNumberRTruedivProtocol::__rtruediv__
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_truediv() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberTruedivProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_true_divide,
|
|
||||||
py_binary_num_func!(PyNumberTruedivProtocol, Self::__truediv__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_rtruediv() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberRTruedivProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_true_divide,
|
|
||||||
py_binary_reversed_num_func!(PyNumberRTruedivProtocol, Self::__rtruediv__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_ifloordiv() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberIFloordivProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_inplace_floor_divide,
|
|
||||||
py_binary_self_func!(PyNumberIFloordivProtocol, Self::__ifloordiv__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_itruediv() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberITruedivProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_inplace_true_divide,
|
|
||||||
py_binary_self_func!(PyNumberITruedivProtocol, Self::__itruediv__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_index() -> TypedSlot<ffi::unaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberIndexProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_index,
|
|
||||||
py_unary_func!(PyNumberIndexProtocol, Self::__index__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_matmul_rmatmul() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberMatmulProtocol<'p> + for<'p> PyNumberRMatmulProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_matrix_multiply,
|
|
||||||
py_binary_fallback_num_func!(
|
|
||||||
Self,
|
|
||||||
PyNumberMatmulProtocol::__matmul__,
|
|
||||||
PyNumberRMatmulProtocol::__rmatmul__
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_matmul() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberMatmulProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_matrix_multiply,
|
|
||||||
py_binary_num_func!(PyNumberMatmulProtocol, Self::__matmul__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_rmatmul() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberRMatmulProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_matrix_multiply,
|
|
||||||
py_binary_reversed_num_func!(PyNumberRMatmulProtocol, Self::__rmatmul__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_imatmul() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyNumberIMatmulProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_nb_inplace_matrix_multiply,
|
|
||||||
py_binary_self_func!(PyNumberIMatmulProtocol, Self::__imatmul__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'p, T> PyNumberSlots for T where T: PyNumberProtocol<'p> {}
|
py_binary_self_func!(ilshift, PyNumberILShiftProtocol, T::__ilshift__);
|
||||||
|
py_binary_self_func!(irshift, PyNumberIRShiftProtocol, T::__irshift__);
|
||||||
|
py_binary_self_func!(iand, PyNumberIAndProtocol, T::__iand__);
|
||||||
|
py_binary_self_func!(ixor, PyNumberIXorProtocol, T::__ixor__);
|
||||||
|
py_binary_self_func!(ior, PyNumberIOrProtocol, T::__ior__);
|
||||||
|
py_binary_fallback_num_func!(
|
||||||
|
floordiv_rfloordiv,
|
||||||
|
T,
|
||||||
|
PyNumberFloordivProtocol::__floordiv__,
|
||||||
|
PyNumberRFloordivProtocol::__rfloordiv__
|
||||||
|
);
|
||||||
|
py_binary_num_func!(floordiv, PyNumberFloordivProtocol, T::__floordiv__);
|
||||||
|
py_binary_reversed_num_func!(rfloordiv, PyNumberRFloordivProtocol, T::__rfloordiv__);
|
||||||
|
py_binary_fallback_num_func!(
|
||||||
|
truediv_rtruediv,
|
||||||
|
T,
|
||||||
|
PyNumberTruedivProtocol::__truediv__,
|
||||||
|
PyNumberRTruedivProtocol::__rtruediv__
|
||||||
|
);
|
||||||
|
py_binary_num_func!(truediv, PyNumberTruedivProtocol, T::__truediv__);
|
||||||
|
py_binary_reversed_num_func!(rtruediv, PyNumberRTruedivProtocol, T::__rtruediv__);
|
||||||
|
py_binary_self_func!(ifloordiv, PyNumberIFloordivProtocol, T::__ifloordiv__);
|
||||||
|
py_binary_self_func!(itruediv, PyNumberITruedivProtocol, T::__itruediv__);
|
||||||
|
py_unary_func!(index, PyNumberIndexProtocol, T::__index__);
|
||||||
|
py_binary_fallback_num_func!(
|
||||||
|
matmul_rmatmul,
|
||||||
|
T,
|
||||||
|
PyNumberMatmulProtocol::__matmul__,
|
||||||
|
PyNumberRMatmulProtocol::__rmatmul__
|
||||||
|
);
|
||||||
|
py_binary_num_func!(matmul, PyNumberMatmulProtocol, T::__matmul__);
|
||||||
|
py_binary_reversed_num_func!(rmatmul, PyNumberRMatmulProtocol, T::__rmatmul__);
|
||||||
|
py_binary_self_func!(imatmul, PyNumberIMatmulProtocol, T::__imatmul__);
|
||||||
|
|
|
@ -1,78 +1,147 @@
|
||||||
use crate::ffi;
|
use crate::ffi;
|
||||||
#[cfg(not(Py_LIMITED_API))]
|
use std::marker::PhantomData;
|
||||||
use crate::ffi::PyBufferProcs;
|
|
||||||
|
|
||||||
/// ABI3 doesn't have buffer APIs, so here we define the empty one.
|
|
||||||
#[cfg(Py_LIMITED_API)]
|
|
||||||
#[doc(hidden)]
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct PyBufferProcs;
|
|
||||||
|
|
||||||
// Note(kngwyu): default implementations are for rust-numpy. Please don't remove them.
|
// Note(kngwyu): default implementations are for rust-numpy. Please don't remove them.
|
||||||
pub trait PyProtoMethods {
|
pub trait PyProtoMethods {
|
||||||
fn get_type_slots() -> Vec<ffi::PyType_Slot> {
|
fn for_each_proto_slot<Visitor: FnMut(ffi::PyType_Slot)>(_visitor: Visitor) {}
|
||||||
vec![]
|
fn get_buffer() -> Option<&'static PyBufferProcs> {
|
||||||
}
|
|
||||||
fn get_buffer() -> Option<PyBufferProcs> {
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Typed version of `ffi::PyType_Slot`
|
pub struct PyClassProtocols<T>(PhantomData<T>);
|
||||||
#[doc(hidden)]
|
|
||||||
pub struct TypedSlot<T: Sized>(pub std::os::raw::c_int, pub T);
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
impl<T> PyClassProtocols<T> {
|
||||||
pub enum PyProtoMethodDef {
|
pub fn new() -> Self {
|
||||||
Slots(Vec<ffi::PyType_Slot>),
|
Self(PhantomData)
|
||||||
Buffer(PyBufferProcs),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Vec<ffi::PyType_Slot>> for PyProtoMethodDef {
|
|
||||||
fn from(slots: Vec<ffi::PyType_Slot>) -> Self {
|
|
||||||
PyProtoMethodDef::Slots(slots)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<PyBufferProcs> for PyProtoMethodDef {
|
impl<T> Default for PyClassProtocols<T> {
|
||||||
fn from(buffer_procs: PyBufferProcs) -> Self {
|
fn default() -> Self {
|
||||||
PyProtoMethodDef::Buffer(buffer_procs)
|
Self::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
impl<T> Clone for PyClassProtocols<T> {
|
||||||
#[cfg(feature = "macros")]
|
fn clone(&self) -> Self {
|
||||||
pub trait PyProtoInventory: inventory::Collect {
|
Self::new()
|
||||||
fn new(methods: PyProtoMethodDef) -> Self;
|
}
|
||||||
fn get(&'static self) -> &'static PyProtoMethodDef;
|
}
|
||||||
}
|
|
||||||
|
impl<T> Copy for PyClassProtocols<T> {}
|
||||||
#[doc(hidden)]
|
|
||||||
#[cfg(feature = "macros")]
|
// All traits describing slots, as well as the fallback implementations for unimplemented protos
|
||||||
pub trait HasProtoInventory {
|
//
|
||||||
type ProtoMethods: PyProtoInventory;
|
// Protos which are implented use dtolnay specialization to implement for PyClassProtocols<T>.
|
||||||
}
|
//
|
||||||
|
// See https://github.com/dtolnay/case-studies/blob/master/autoref-specialization/README.md
|
||||||
#[cfg(feature = "macros")]
|
|
||||||
impl<T: HasProtoInventory> PyProtoMethods for T {
|
pub trait PyObjectProtocolSlots<T> {
|
||||||
fn get_type_slots() -> Vec<ffi::PyType_Slot> {
|
fn object_protocol_slots(self) -> &'static [ffi::PyType_Slot];
|
||||||
inventory::iter::<T::ProtoMethods>
|
}
|
||||||
.into_iter()
|
|
||||||
.filter_map(|def| match def.get() {
|
impl<T> PyObjectProtocolSlots<T> for &'_ PyClassProtocols<T> {
|
||||||
PyProtoMethodDef::Slots(slots) => Some(slots),
|
fn object_protocol_slots(self) -> &'static [ffi::PyType_Slot] {
|
||||||
PyProtoMethodDef::Buffer(_) => None,
|
&[]
|
||||||
})
|
}
|
||||||
.flatten()
|
}
|
||||||
.cloned()
|
|
||||||
.collect()
|
pub trait PyDescrProtocolSlots<T> {
|
||||||
}
|
fn descr_protocol_slots(self) -> &'static [ffi::PyType_Slot];
|
||||||
|
}
|
||||||
fn get_buffer() -> Option<PyBufferProcs> {
|
|
||||||
inventory::iter::<T::ProtoMethods>
|
impl<T> PyDescrProtocolSlots<T> for &'_ PyClassProtocols<T> {
|
||||||
.into_iter()
|
fn descr_protocol_slots(self) -> &'static [ffi::PyType_Slot] {
|
||||||
.find_map(|def| match def.get() {
|
&[]
|
||||||
PyProtoMethodDef::Slots(_) => None,
|
}
|
||||||
PyProtoMethodDef::Buffer(buf) => Some(buf.clone()),
|
}
|
||||||
})
|
|
||||||
|
pub trait PyGCProtocolSlots<T> {
|
||||||
|
fn gc_protocol_slots(self) -> &'static [ffi::PyType_Slot];
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> PyGCProtocolSlots<T> for &'_ PyClassProtocols<T> {
|
||||||
|
fn gc_protocol_slots(self) -> &'static [ffi::PyType_Slot] {
|
||||||
|
&[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait PyIterProtocolSlots<T> {
|
||||||
|
fn iter_protocol_slots(self) -> &'static [ffi::PyType_Slot];
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> PyIterProtocolSlots<T> for &'_ PyClassProtocols<T> {
|
||||||
|
fn iter_protocol_slots(self) -> &'static [ffi::PyType_Slot] {
|
||||||
|
&[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait PyMappingProtocolSlots<T> {
|
||||||
|
fn mapping_protocol_slots(self) -> &'static [ffi::PyType_Slot];
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> PyMappingProtocolSlots<T> for &'_ PyClassProtocols<T> {
|
||||||
|
fn mapping_protocol_slots(self) -> &'static [ffi::PyType_Slot] {
|
||||||
|
&[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait PyNumberProtocolSlots<T> {
|
||||||
|
fn number_protocol_slots(self) -> &'static [ffi::PyType_Slot];
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> PyNumberProtocolSlots<T> for &'_ PyClassProtocols<T> {
|
||||||
|
fn number_protocol_slots(self) -> &'static [ffi::PyType_Slot] {
|
||||||
|
&[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait PyAsyncProtocolSlots<T> {
|
||||||
|
fn async_protocol_slots(self) -> &'static [ffi::PyType_Slot];
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> PyAsyncProtocolSlots<T> for &'_ PyClassProtocols<T> {
|
||||||
|
fn async_protocol_slots(self) -> &'static [ffi::PyType_Slot] {
|
||||||
|
&[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait PySequenceProtocolSlots<T> {
|
||||||
|
fn sequence_protocol_slots(self) -> &'static [ffi::PyType_Slot];
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> PySequenceProtocolSlots<T> for &'_ PyClassProtocols<T> {
|
||||||
|
fn sequence_protocol_slots(self) -> &'static [ffi::PyType_Slot] {
|
||||||
|
&[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait PyBufferProtocolSlots<T> {
|
||||||
|
fn buffer_protocol_slots(self) -> &'static [ffi::PyType_Slot];
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> PyBufferProtocolSlots<T> for &'_ PyClassProtocols<T> {
|
||||||
|
fn buffer_protocol_slots(self) -> &'static [ffi::PyType_Slot] {
|
||||||
|
&[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// On Python < 3.9 setting the buffer protocol using slots doesn't work, so these procs are used
|
||||||
|
// on those versions to set the slots manually (on the limited API).
|
||||||
|
|
||||||
|
#[cfg(not(Py_LIMITED_API))]
|
||||||
|
pub use ffi::PyBufferProcs;
|
||||||
|
|
||||||
|
#[cfg(Py_LIMITED_API)]
|
||||||
|
pub struct PyBufferProcs;
|
||||||
|
|
||||||
|
pub trait PyBufferProtocolProcs<T> {
|
||||||
|
fn buffer_procs(self) -> Option<&'static PyBufferProcs>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> PyBufferProtocolProcs<T> for &'_ PyClassProtocols<T> {
|
||||||
|
fn buffer_procs(self) -> Option<&'static PyBufferProcs> {
|
||||||
|
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 super::proto_methods::TypedSlot;
|
|
||||||
use crate::callback::IntoPyCallbackOutput;
|
use crate::callback::IntoPyCallbackOutput;
|
||||||
use crate::derive_utils::TryFromPyCell;
|
use crate::derive_utils::TryFromPyCell;
|
||||||
use crate::err::PyResult;
|
use crate::err::PyResult;
|
||||||
|
@ -86,41 +85,9 @@ pub trait PyAsyncAexitProtocol<'p>: PyAsyncProtocol<'p> {
|
||||||
type Result: IntoPyCallbackOutput<PyObject>;
|
type Result: IntoPyCallbackOutput<PyObject>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extension trait for proc-macro backend.
|
py_unarys_func!(await_, PyAsyncAwaitProtocol, Self::__await__);
|
||||||
#[doc(hidden)]
|
py_unarys_func!(aiter, PyAsyncAiterProtocol, Self::__aiter__);
|
||||||
pub trait PyAsyncSlots {
|
py_unarys_func!(anext, PyAsyncAnextProtocol, Self::__anext__);
|
||||||
fn get_await() -> TypedSlot<ffi::unaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyAsyncAwaitProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_am_await,
|
|
||||||
py_unarys_func!(PyAsyncAwaitProtocol, Self::__await__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_aiter() -> TypedSlot<ffi::unaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyAsyncAiterProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_am_aiter,
|
|
||||||
py_unarys_func!(PyAsyncAiterProtocol, Self::__aiter__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_anext() -> TypedSlot<ffi::unaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PyAsyncAnextProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_am_anext,
|
|
||||||
py_unarys_func!(PyAsyncAnextProtocol, Self::__anext__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'p, T> PyAsyncSlots for T where T: PyAsyncProtocol<'p> {}
|
|
||||||
|
|
||||||
/// Output of `__anext__`.
|
/// Output of `__anext__`.
|
||||||
pub enum IterANextOutput<T, U> {
|
pub enum IterANextOutput<T, U> {
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
//! Python Sequence Interface
|
//! Python Sequence Interface
|
||||||
//! Trait and support implementation for implementing sequence
|
//! Trait and support implementation for implementing sequence
|
||||||
|
|
||||||
use super::proto_methods::TypedSlot;
|
|
||||||
use crate::callback::IntoPyCallbackOutput;
|
use crate::callback::IntoPyCallbackOutput;
|
||||||
use crate::conversion::{FromPyObject, IntoPy};
|
use crate::conversion::{FromPyObject, IntoPy};
|
||||||
use crate::err::PyErr;
|
use crate::err::PyErr;
|
||||||
|
@ -129,61 +128,20 @@ pub trait PySequenceInplaceRepeatProtocol<'p>:
|
||||||
type Result: IntoPyCallbackOutput<Self>;
|
type Result: IntoPyCallbackOutput<Self>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extension trait for proc-macro backend.
|
py_len_func!(len, PySequenceLenProtocol, Self::__len__);
|
||||||
|
py_binary_func!(concat, PySequenceConcatProtocol, Self::__concat__);
|
||||||
|
py_ssizearg_func!(repeat, PySequenceRepeatProtocol, Self::__repeat__);
|
||||||
|
py_ssizearg_func!(getitem, PySequenceGetItemProtocol, Self::__getitem__);
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub trait PySequenceSlots {
|
pub unsafe extern "C" fn setitem<T>(
|
||||||
fn get_len() -> TypedSlot<ffi::lenfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PySequenceLenProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_sq_length,
|
|
||||||
py_len_func!(PySequenceLenProtocol, Self::__len__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_concat() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PySequenceConcatProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_sq_concat,
|
|
||||||
py_binary_func!(PySequenceConcatProtocol, Self::__concat__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_repeat() -> TypedSlot<ffi::ssizeargfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PySequenceRepeatProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_sq_repeat,
|
|
||||||
py_ssizearg_func!(PySequenceRepeatProtocol, Self::__repeat__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_getitem() -> TypedSlot<ffi::ssizeargfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PySequenceGetItemProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_sq_item,
|
|
||||||
py_ssizearg_func!(PySequenceGetItemProtocol, Self::__getitem__),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_setitem() -> TypedSlot<ffi::ssizeobjargproc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PySequenceSetItemProtocol<'p>,
|
|
||||||
{
|
|
||||||
unsafe extern "C" fn wrap<T>(
|
|
||||||
slf: *mut ffi::PyObject,
|
slf: *mut ffi::PyObject,
|
||||||
key: ffi::Py_ssize_t,
|
key: ffi::Py_ssize_t,
|
||||||
value: *mut ffi::PyObject,
|
value: *mut ffi::PyObject,
|
||||||
) -> c_int
|
) -> c_int
|
||||||
where
|
where
|
||||||
T: for<'p> PySequenceSetItemProtocol<'p>,
|
T: for<'p> PySequenceSetItemProtocol<'p>,
|
||||||
{
|
{
|
||||||
crate::callback_body!(py, {
|
crate::callback_body!(py, {
|
||||||
let slf = py.from_borrowed_ptr::<PyCell<T>>(slf);
|
let slf = py.from_borrowed_ptr::<PyCell<T>>(slf);
|
||||||
|
|
||||||
|
@ -199,23 +157,17 @@ pub trait PySequenceSlots {
|
||||||
let value = value.extract()?;
|
let value = value.extract()?;
|
||||||
crate::callback::convert(py, slf.__setitem__(key.into(), value))
|
crate::callback::convert(py, slf.__setitem__(key.into(), value))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
TypedSlot(ffi::Py_sq_ass_item, wrap::<Self>)
|
#[doc(hidden)]
|
||||||
}
|
pub unsafe extern "C" fn delitem<T>(
|
||||||
|
|
||||||
fn get_delitem() -> TypedSlot<ffi::ssizeobjargproc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PySequenceDelItemProtocol<'p>,
|
|
||||||
{
|
|
||||||
unsafe extern "C" fn wrap<T>(
|
|
||||||
slf: *mut ffi::PyObject,
|
slf: *mut ffi::PyObject,
|
||||||
key: ffi::Py_ssize_t,
|
key: ffi::Py_ssize_t,
|
||||||
value: *mut ffi::PyObject,
|
value: *mut ffi::PyObject,
|
||||||
) -> c_int
|
) -> c_int
|
||||||
where
|
where
|
||||||
T: for<'p> PySequenceDelItemProtocol<'p>,
|
T: for<'p> PySequenceDelItemProtocol<'p>,
|
||||||
{
|
{
|
||||||
crate::callback_body!(py, {
|
crate::callback_body!(py, {
|
||||||
let slf = py.from_borrowed_ptr::<PyCell<T>>(slf);
|
let slf = py.from_borrowed_ptr::<PyCell<T>>(slf);
|
||||||
|
|
||||||
|
@ -228,23 +180,17 @@ pub trait PySequenceSlots {
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
TypedSlot(ffi::Py_sq_ass_item, wrap::<Self>)
|
#[doc(hidden)]
|
||||||
}
|
pub unsafe extern "C" fn setdelitem<T>(
|
||||||
|
|
||||||
fn get_setdelitem() -> TypedSlot<ffi::ssizeobjargproc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PySequenceDelItemProtocol<'p> + for<'p> PySequenceSetItemProtocol<'p>,
|
|
||||||
{
|
|
||||||
unsafe extern "C" fn wrap<T>(
|
|
||||||
slf: *mut ffi::PyObject,
|
slf: *mut ffi::PyObject,
|
||||||
key: ffi::Py_ssize_t,
|
key: ffi::Py_ssize_t,
|
||||||
value: *mut ffi::PyObject,
|
value: *mut ffi::PyObject,
|
||||||
) -> c_int
|
) -> c_int
|
||||||
where
|
where
|
||||||
T: for<'p> PySequenceSetItemProtocol<'p> + for<'p> PySequenceDelItemProtocol<'p>,
|
T: for<'p> PySequenceSetItemProtocol<'p> + for<'p> PySequenceDelItemProtocol<'p>,
|
||||||
{
|
{
|
||||||
crate::callback_body!(py, {
|
crate::callback_body!(py, {
|
||||||
let slf = py.from_borrowed_ptr::<PyCell<T>>(slf);
|
let slf = py.from_borrowed_ptr::<PyCell<T>>(slf);
|
||||||
|
|
||||||
|
@ -257,49 +203,24 @@ pub trait PySequenceSlots {
|
||||||
slf_.__setitem__(key.into(), value).convert(py)
|
slf_.__setitem__(key.into(), value).convert(py)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
TypedSlot(ffi::Py_sq_ass_item, wrap::<Self>)
|
py_binary_func!(
|
||||||
}
|
contains,
|
||||||
|
PySequenceContainsProtocol,
|
||||||
fn get_contains() -> TypedSlot<ffi::objobjproc>
|
Self::__contains__,
|
||||||
where
|
c_int
|
||||||
Self: for<'p> PySequenceContainsProtocol<'p>,
|
);
|
||||||
{
|
py_binary_func!(
|
||||||
TypedSlot(
|
inplace_concat,
|
||||||
ffi::Py_sq_contains,
|
|
||||||
py_binary_func!(PySequenceContainsProtocol, Self::__contains__, c_int),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_inplace_concat() -> TypedSlot<ffi::binaryfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PySequenceInplaceConcatProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_sq_inplace_concat,
|
|
||||||
py_binary_func!(
|
|
||||||
PySequenceInplaceConcatProtocol,
|
PySequenceInplaceConcatProtocol,
|
||||||
Self::__inplace_concat__,
|
Self::__inplace_concat__,
|
||||||
*mut ffi::PyObject,
|
*mut ffi::PyObject,
|
||||||
call_mut
|
call_mut
|
||||||
),
|
);
|
||||||
)
|
py_ssizearg_func!(
|
||||||
}
|
inplace_repeat,
|
||||||
|
|
||||||
fn get_inplace_repeat() -> TypedSlot<ffi::ssizeargfunc>
|
|
||||||
where
|
|
||||||
Self: for<'p> PySequenceInplaceRepeatProtocol<'p>,
|
|
||||||
{
|
|
||||||
TypedSlot(
|
|
||||||
ffi::Py_sq_inplace_repeat,
|
|
||||||
py_ssizearg_func!(
|
|
||||||
PySequenceInplaceRepeatProtocol,
|
PySequenceInplaceRepeatProtocol,
|
||||||
Self::__inplace_repeat__,
|
Self::__inplace_repeat__,
|
||||||
call_mut
|
call_mut
|
||||||
),
|
);
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'p, T> PySequenceSlots for T where T: PySequenceProtocol<'p> {}
|
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
use std::os::raw::c_int;
|
use std::os::raw::c_int;
|
||||||
|
|
||||||
|
#[cfg(not(Py_LIMITED_API))]
|
||||||
|
pub const Py_bf_getbuffer: c_int = 1;
|
||||||
|
#[cfg(not(Py_LIMITED_API))]
|
||||||
|
pub const Py_bf_releasebuffer: c_int = 2;
|
||||||
pub const Py_mp_ass_subscript: c_int = 3;
|
pub const Py_mp_ass_subscript: c_int = 3;
|
||||||
pub const Py_mp_length: c_int = 4;
|
pub const Py_mp_length: c_int = 4;
|
||||||
pub const Py_mp_subscript: c_int = 5;
|
pub const Py_mp_subscript: c_int = 5;
|
||||||
|
|
|
@ -339,16 +339,15 @@ macro_rules! py_run_impl {
|
||||||
use $crate::ToPyObject;
|
use $crate::ToPyObject;
|
||||||
let d = [$((stringify!($val), $val.to_object($py)),)+].into_py_dict($py);
|
let d = [$((stringify!($val), $val.to_object($py)),)+].into_py_dict($py);
|
||||||
|
|
||||||
$py.run($code, None, Some(d))
|
if let Err(e) = $py.run($code, None, Some(d)) {
|
||||||
.map_err(|e| {
|
|
||||||
e.print($py);
|
e.print($py);
|
||||||
// So when this c api function the last line called printed the error to stderr,
|
// So when this c api function the last line called printed the error to stderr,
|
||||||
// the output is only written into a buffer which is never flushed because we
|
// the output is only written into a buffer which is never flushed because we
|
||||||
// panic before flushing. This is where this hack comes into place
|
// panic before flushing. This is where this hack comes into place
|
||||||
$py.run("import sys; sys.stderr.flush()", None, None)
|
$py.run("import sys; sys.stderr.flush()", None, None)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
})
|
panic!($code.to_string())
|
||||||
.expect($code)
|
}
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -191,11 +191,11 @@ where
|
||||||
|
|
||||||
// protocol methods
|
// protocol methods
|
||||||
let mut has_gc_methods = false;
|
let mut has_gc_methods = false;
|
||||||
for slot in T::get_type_slots() {
|
T::for_each_proto_slot(|slot| {
|
||||||
has_gc_methods |= slot.slot == ffi::Py_tp_clear;
|
has_gc_methods |= slot.slot == ffi::Py_tp_clear;
|
||||||
has_gc_methods |= slot.slot == ffi::Py_tp_traverse;
|
has_gc_methods |= slot.slot == ffi::Py_tp_traverse;
|
||||||
slots.0.push(slot);
|
slots.0.push(slot);
|
||||||
}
|
});
|
||||||
|
|
||||||
slots.push(0, ptr::null_mut());
|
slots.push(0, ptr::null_mut());
|
||||||
let mut spec = ffi::PyType_Spec {
|
let mut spec = ffi::PyType_Spec {
|
||||||
|
@ -238,6 +238,9 @@ fn tp_init_additional<T: PyClass>(type_object: *mut ffi::PyTypeObject) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setting buffer protocols via slots doesn't work until Python 3.9, so on older versions we
|
||||||
|
// must manually fixup the type object.
|
||||||
|
#[cfg(not(Py_3_9))]
|
||||||
if let Some(buffer) = T::get_buffer() {
|
if let Some(buffer) = T::get_buffer() {
|
||||||
unsafe {
|
unsafe {
|
||||||
(*(*type_object).tp_as_buffer).bf_getbuffer = buffer.bf_getbuffer;
|
(*(*type_object).tp_as_buffer).bf_getbuffer = buffer.bf_getbuffer;
|
||||||
|
|
Loading…
Reference in New Issue