generate method defs from protocols
This commit is contained in:
parent
266e608dc5
commit
eb64aa11ac
|
@ -10,7 +10,7 @@ install:
|
||||||
- python -c "import sysconfig; print('\n'.join(map(repr,sorted(sysconfig.get_config_vars().items()))))"
|
- python -c "import sysconfig; print('\n'.join(map(repr,sorted(sysconfig.get_config_vars().items()))))"
|
||||||
- mkdir ~/rust-installer
|
- mkdir ~/rust-installer
|
||||||
- curl -sL https://static.rust-lang.org/rustup.sh -o ~/rust-installer/rustup.sh
|
- curl -sL https://static.rust-lang.org/rustup.sh -o ~/rust-installer/rustup.sh
|
||||||
- sh ~/rust-installer/rustup.sh --prefix=~/rust --spec=$RUST_VERSION -y --disable-sudo
|
- sh ~/rust-installer/rustup.sh --prefix=~/rust --spec=$RUST_VERSION -y
|
||||||
- export PATH="$HOME/rust/bin:$PATH"
|
- export PATH="$HOME/rust/bin:$PATH"
|
||||||
- export PYTHON_LIB=$(python -c "import sysconfig; print(sysconfig.get_config_var('LIBDIR'))")
|
- export PYTHON_LIB=$(python -c "import sysconfig; print(sysconfig.get_config_var('LIBDIR'))")
|
||||||
- find $PYTHON_LIB
|
- find $PYTHON_LIB
|
||||||
|
|
|
@ -9,6 +9,10 @@ pub enum MethodProto {
|
||||||
Unary{name: &'static str, proto: &'static str},
|
Unary{name: &'static str, proto: &'static str},
|
||||||
Binary{name: &'static str, arg: &'static str, proto: &'static str},
|
Binary{name: &'static str, arg: &'static str, proto: &'static str},
|
||||||
Ternary{name: &'static str, arg1: &'static str, arg2: &'static str, proto: &'static str},
|
Ternary{name: &'static str, arg1: &'static str, arg2: &'static str, proto: &'static str},
|
||||||
|
Quaternary{name: &'static str,
|
||||||
|
arg1: &'static str,
|
||||||
|
arg2: &'static str,
|
||||||
|
arg3: &'static str, proto: &'static str},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MethodProto {
|
impl MethodProto {
|
||||||
|
@ -19,6 +23,7 @@ impl MethodProto {
|
||||||
MethodProto::Unary{name: n, proto: _} => n == name,
|
MethodProto::Unary{name: n, proto: _} => n == name,
|
||||||
MethodProto::Binary{name: n, arg: _, proto: _} => n == name,
|
MethodProto::Binary{name: n, arg: _, proto: _} => n == name,
|
||||||
MethodProto::Ternary{name: n, arg1: _, arg2: _, proto: _} => n == name,
|
MethodProto::Ternary{name: n, arg1: _, arg2: _, proto: _} => n == name,
|
||||||
|
MethodProto::Quaternary{name: n, arg1: _, arg2: _, arg3: _, proto: _} => n == name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,6 +85,26 @@ pub fn impl_method_proto(cls: &Box<syn::Ty>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
MethodProto::Quaternary{name: _, arg1, arg2, arg3, proto} => {
|
||||||
|
let p = syn::Ident::from(proto);
|
||||||
|
let arg1_name = syn::Ident::from(arg1);
|
||||||
|
let arg1_ty = get_arg_ty(sig, 2);
|
||||||
|
let arg2_name = syn::Ident::from(arg2);
|
||||||
|
let arg2_ty = get_arg_ty(sig, 3);
|
||||||
|
let arg3_name = syn::Ident::from(arg3);
|
||||||
|
let arg3_ty = get_arg_ty(sig, 4);
|
||||||
|
let succ = get_res_success(ty);
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
impl #p for #cls {
|
||||||
|
type #arg1_name = #arg1_ty;
|
||||||
|
type #arg2_name = #arg2_ty;
|
||||||
|
type #arg3_name = #arg3_ty;
|
||||||
|
type Success = #succ;
|
||||||
|
type Result = #ty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => panic!("not supported"),
|
_ => panic!("not supported"),
|
||||||
|
@ -87,10 +112,31 @@ pub fn impl_method_proto(cls: &Box<syn::Ty>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: better arg ty detection
|
||||||
fn get_arg_ty(sig: &syn::MethodSig, idx: usize) -> syn::Ty {
|
fn get_arg_ty(sig: &syn::MethodSig, idx: usize) -> syn::Ty {
|
||||||
match sig.decl.inputs[idx] {
|
match sig.decl.inputs[idx] {
|
||||||
syn::FnArg::Captured(_, ref arg_ty) => {
|
syn::FnArg::Captured(_, ref arg_ty) => {
|
||||||
arg_ty.clone()
|
match arg_ty {
|
||||||
|
&syn::Ty::Path(_, ref path) => {
|
||||||
|
// use only last path segment for Option<>
|
||||||
|
let seg = path.segments.last().unwrap().clone();
|
||||||
|
if seg.ident.as_ref() == "Option" {
|
||||||
|
match seg.parameters {
|
||||||
|
syn::PathParameters::AngleBracketed(ref data) => {
|
||||||
|
if let Some(ty) = data.types.last() {
|
||||||
|
return ty.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
arg_ty.clone()
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
arg_ty.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
_ =>
|
_ =>
|
||||||
panic!("not supported"),
|
panic!("not supported"),
|
||||||
|
|
|
@ -25,9 +25,9 @@ fn impl_methods(ty: &Box<syn::Ty>, impls: &mut Vec<syn::ImplItem>) -> Tokens {
|
||||||
let mut methods = Vec::new();
|
let mut methods = Vec::new();
|
||||||
for iimpl in impls.iter_mut() {
|
for iimpl in impls.iter_mut() {
|
||||||
match iimpl.node {
|
match iimpl.node {
|
||||||
syn::ImplItemKind::Method(ref mut sig, ref mut block) => {
|
syn::ImplItemKind::Method(ref mut sig, _) => {
|
||||||
methods.push(py_method::gen_py_method(
|
methods.push(py_method::gen_py_method(
|
||||||
ty, &iimpl.ident, sig, block, &mut iimpl.attrs));
|
ty, &iimpl.ident, sig, &mut iimpl.attrs));
|
||||||
},
|
},
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ enum FnSpec {
|
||||||
|
|
||||||
|
|
||||||
pub fn gen_py_method<'a>(cls: &Box<syn::Ty>, name: &syn::Ident,
|
pub fn gen_py_method<'a>(cls: &Box<syn::Ty>, name: &syn::Ident,
|
||||||
sig: &mut syn::MethodSig, _block: &mut syn::Block,
|
sig: &mut syn::MethodSig,
|
||||||
meth_attrs: &mut Vec<syn::Attribute>) -> Tokens
|
meth_attrs: &mut Vec<syn::Attribute>) -> Tokens
|
||||||
{
|
{
|
||||||
check_generic(name, sig);
|
check_generic(name, sig);
|
||||||
|
|
|
@ -11,10 +11,15 @@ struct Methods {
|
||||||
methods: &'static [&'static str],
|
methods: &'static [&'static str],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct PyMethod {
|
||||||
|
name: &'static str,
|
||||||
|
proto: &'static str,
|
||||||
|
}
|
||||||
|
|
||||||
struct Proto {
|
struct Proto {
|
||||||
name: &'static str,
|
name: &'static str,
|
||||||
//py_methods: &'static [&'static str],
|
|
||||||
methods: &'static [MethodProto],
|
methods: &'static [MethodProto],
|
||||||
|
py_methods: &'static [PyMethod],
|
||||||
}
|
}
|
||||||
|
|
||||||
static DEFAULT_METHODS: Methods = Methods {
|
static DEFAULT_METHODS: Methods = Methods {
|
||||||
|
@ -40,9 +45,8 @@ static NUM_METHODS: Methods = Methods {
|
||||||
|
|
||||||
static ASYNC: Proto = Proto {
|
static ASYNC: Proto = Proto {
|
||||||
name: "Async",
|
name: "Async",
|
||||||
//py_methods: &[],
|
|
||||||
methods: &[
|
methods: &[
|
||||||
MethodProto::Unary{
|
MethodProto::Unary {
|
||||||
name: "__await__",
|
name: "__await__",
|
||||||
proto: "_pyo3::class::async::PyAsyncAwaitProtocol"},
|
proto: "_pyo3::class::async::PyAsyncAwaitProtocol"},
|
||||||
MethodProto::Unary{
|
MethodProto::Unary{
|
||||||
|
@ -51,12 +55,29 @@ static ASYNC: Proto = Proto {
|
||||||
MethodProto::Unary{
|
MethodProto::Unary{
|
||||||
name: "__anext__",
|
name: "__anext__",
|
||||||
proto: "_pyo3::class::async::PyAsyncAnextProtocol"},
|
proto: "_pyo3::class::async::PyAsyncAnextProtocol"},
|
||||||
|
MethodProto::Unary{
|
||||||
|
name: "__aenter__",
|
||||||
|
proto: "_pyo3::class::async::PyAsyncAenterProtocol"},
|
||||||
|
MethodProto::Quaternary {
|
||||||
|
name: "__aexit__",
|
||||||
|
arg1: "ExcType", arg2: "ExcValue", arg3: "Traceback",
|
||||||
|
proto: "_pyo3::class::async::PyAsyncAexitProtocol"},
|
||||||
|
],
|
||||||
|
py_methods: &[
|
||||||
|
PyMethod {
|
||||||
|
name: "__aenter__",
|
||||||
|
proto: "_pyo3::class::async::PyAsyncAenterProtocolImpl",
|
||||||
|
},
|
||||||
|
PyMethod {
|
||||||
|
name: "__aexit__",
|
||||||
|
proto: "_pyo3::class::async::PyAsyncAexitProtocolImpl",
|
||||||
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
static ITER: Proto = Proto {
|
static ITER: Proto = Proto {
|
||||||
name: "Iter",
|
name: "Iter",
|
||||||
//py_methods: &[],
|
py_methods: &[],
|
||||||
methods: &[
|
methods: &[
|
||||||
MethodProto::Unary{
|
MethodProto::Unary{
|
||||||
name: "__iter__",
|
name: "__iter__",
|
||||||
|
@ -70,7 +91,7 @@ static ITER: Proto = Proto {
|
||||||
|
|
||||||
static MAPPING: Proto = Proto {
|
static MAPPING: Proto = Proto {
|
||||||
name: "Mapping",
|
name: "Mapping",
|
||||||
//py_methods: &[],
|
py_methods: &[],
|
||||||
methods: &[
|
methods: &[
|
||||||
MethodProto::Len{
|
MethodProto::Len{
|
||||||
name: "__len__",
|
name: "__len__",
|
||||||
|
@ -140,6 +161,7 @@ pub fn build_py_proto(ast: &mut syn::Item) -> Tokens {
|
||||||
|
|
||||||
fn impl_proto_impl(ty: &Box<syn::Ty>, impls: &mut Vec<syn::ImplItem>, proto: &Proto) -> Tokens {
|
fn impl_proto_impl(ty: &Box<syn::Ty>, impls: &mut Vec<syn::ImplItem>, proto: &Proto) -> Tokens {
|
||||||
let mut tokens = Tokens::new();
|
let mut tokens = Tokens::new();
|
||||||
|
let mut py_methods = Vec::new();
|
||||||
|
|
||||||
for iimpl in impls.iter_mut() {
|
for iimpl in impls.iter_mut() {
|
||||||
match iimpl.node {
|
match iimpl.node {
|
||||||
|
@ -149,6 +171,27 @@ fn impl_proto_impl(ty: &Box<syn::Ty>, impls: &mut Vec<syn::ImplItem>, proto: &Pr
|
||||||
impl_method_proto(ty, sig, m).to_tokens(&mut tokens);
|
impl_method_proto(ty, sig, m).to_tokens(&mut tokens);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for m in proto.py_methods {
|
||||||
|
if m.name == iimpl.ident.as_ref() {
|
||||||
|
let name = syn::Ident::from(m.name);
|
||||||
|
let proto = syn::Ident::from(m.proto);
|
||||||
|
|
||||||
|
let meth = py_method::gen_py_method(
|
||||||
|
ty, &iimpl.ident, sig, &mut iimpl.attrs);
|
||||||
|
|
||||||
|
py_methods.push(
|
||||||
|
quote! {
|
||||||
|
impl #proto for #ty
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn #name() -> Option<_pyo3::class::methods::PyMethodDefType> {
|
||||||
|
Some(#meth)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
@ -172,6 +215,8 @@ fn impl_proto_impl(ty: &Box<syn::Ty>, impls: &mut Vec<syn::ImplItem>, proto: &Pr
|
||||||
extern crate pyo3 as _pyo3;
|
extern crate pyo3 as _pyo3;
|
||||||
|
|
||||||
#tokens
|
#tokens
|
||||||
|
|
||||||
|
#(#py_methods)*
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -185,10 +230,10 @@ fn impl_protocol(name: &'static str,
|
||||||
let mut meth = Vec::new();
|
let mut meth = Vec::new();
|
||||||
for iimpl in impls.iter_mut() {
|
for iimpl in impls.iter_mut() {
|
||||||
match iimpl.node {
|
match iimpl.node {
|
||||||
syn::ImplItemKind::Method(ref mut sig, ref mut block) => {
|
syn::ImplItemKind::Method(ref mut sig, _) => {
|
||||||
if methods.methods.contains(&iimpl.ident.as_ref()) {
|
if methods.methods.contains(&iimpl.ident.as_ref()) {
|
||||||
py_methods.push(py_method::gen_py_method(
|
py_methods.push(py_method::gen_py_method(
|
||||||
ty, &iimpl.ident, sig, block, &mut iimpl.attrs));
|
ty, &iimpl.ident, sig, &mut iimpl.attrs));
|
||||||
} else {
|
} else {
|
||||||
meth.push(String::from(iimpl.ident.as_ref()));
|
meth.push(String::from(iimpl.ident.as_ref()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ use ffi;
|
||||||
use err::PyResult;
|
use err::PyResult;
|
||||||
use python::{Python, PythonObject};
|
use python::{Python, PythonObject};
|
||||||
use callback::PyObjectCallbackConverter;
|
use callback::PyObjectCallbackConverter;
|
||||||
|
use class::methods::{PyMethodDef, PyMethodDefType};
|
||||||
|
|
||||||
|
|
||||||
/// Awaitable interface
|
/// Awaitable interface
|
||||||
|
@ -28,9 +29,11 @@ pub trait PyAsyncProtocol: PythonObject {
|
||||||
fn __aenter__(&self, py: Python)
|
fn __aenter__(&self, py: Python)
|
||||||
-> Self::Result where Self: PyAsyncAenterProtocol { unimplemented!() }
|
-> Self::Result where Self: PyAsyncAenterProtocol { unimplemented!() }
|
||||||
|
|
||||||
fn __aexit__(&self, py: Python)
|
fn __aexit__(&self, py: Python,
|
||||||
|
exc_type: Option<Self::ExcType>,
|
||||||
|
exc_value: Option<Self::ExcValue>,
|
||||||
|
traceback: Option<Self::Traceback>)
|
||||||
-> Self::Result where Self: PyAsyncAexitProtocol { unimplemented!() }
|
-> Self::Result where Self: PyAsyncAexitProtocol { unimplemented!() }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -55,6 +58,9 @@ pub trait PyAsyncAenterProtocol: PyAsyncProtocol {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait PyAsyncAexitProtocol: PyAsyncProtocol {
|
pub trait PyAsyncAexitProtocol: PyAsyncProtocol {
|
||||||
|
type ExcType: for<'a> ::FromPyObject<'a>;
|
||||||
|
type ExcValue: for<'a> ::FromPyObject<'a>;
|
||||||
|
type Traceback: for<'a> ::FromPyObject<'a>;
|
||||||
type Success: ::ToPyObject;
|
type Success: ::ToPyObject;
|
||||||
type Result: Into<PyResult<Self::Success>>;
|
type Result: Into<PyResult<Self::Success>>;
|
||||||
}
|
}
|
||||||
|
@ -63,6 +69,8 @@ pub trait PyAsyncAexitProtocol: PyAsyncProtocol {
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub trait PyAsyncProtocolImpl {
|
pub trait PyAsyncProtocolImpl {
|
||||||
fn tp_as_async() -> Option<ffi::PyAsyncMethods>;
|
fn tp_as_async() -> Option<ffi::PyAsyncMethods>;
|
||||||
|
|
||||||
|
fn methods() -> Vec<PyMethodDef>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> PyAsyncProtocolImpl for T {
|
impl<T> PyAsyncProtocolImpl for T {
|
||||||
|
@ -70,6 +78,11 @@ impl<T> PyAsyncProtocolImpl for T {
|
||||||
default fn tp_as_async() -> Option<ffi::PyAsyncMethods> {
|
default fn tp_as_async() -> Option<ffi::PyAsyncMethods> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
default fn methods() -> Vec<PyMethodDef> {
|
||||||
|
Vec::new()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> PyAsyncProtocolImpl for T where T: PyAsyncProtocol {
|
impl<T> PyAsyncProtocolImpl for T where T: PyAsyncProtocol {
|
||||||
|
@ -81,6 +94,22 @@ impl<T> PyAsyncProtocolImpl for T where T: PyAsyncProtocol {
|
||||||
am_anext: Self::am_anext(),
|
am_anext: Self::am_anext(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn methods() -> Vec<PyMethodDef> {
|
||||||
|
let mut methods = Vec::new();
|
||||||
|
|
||||||
|
if let Some(PyMethodDefType::Method(meth)) =
|
||||||
|
<Self as PyAsyncAenterProtocolImpl>::__aenter__() {
|
||||||
|
methods.push(meth)
|
||||||
|
}
|
||||||
|
if let Some(PyMethodDefType::Method(meth)) =
|
||||||
|
<Self as PyAsyncAexitProtocolImpl>::__aexit__() {
|
||||||
|
methods.push(meth)
|
||||||
|
}
|
||||||
|
|
||||||
|
methods
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -151,45 +180,27 @@ impl<T> PyAsyncAnextProtocolImpl for T
|
||||||
}
|
}
|
||||||
|
|
||||||
trait PyAsyncAenterProtocolImpl {
|
trait PyAsyncAenterProtocolImpl {
|
||||||
fn am_aenter() -> Option<ffi::unaryfunc>;
|
fn __aenter__() -> Option<PyMethodDefType>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> PyAsyncAenterProtocolImpl for T
|
impl<T> PyAsyncAenterProtocolImpl for T
|
||||||
where T: PyAsyncProtocol
|
where T: PyAsyncProtocol
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
default fn am_aenter() -> Option<ffi::unaryfunc> {
|
default fn __aenter__() -> Option<PyMethodDefType> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> PyAsyncAenterProtocolImpl for T
|
pub trait PyAsyncAexitProtocolImpl {
|
||||||
where T: PyAsyncAenterProtocol
|
fn __aexit__() -> Option<PyMethodDefType>;
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn am_aenter() -> Option<ffi::unaryfunc> {
|
|
||||||
py_unary_func_!(PyAsyncAenterProtocol, T::__aenter__, PyObjectCallbackConverter)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
trait PyAsyncAexitProtocolImpl {
|
|
||||||
fn am_aexit() -> Option<ffi::unaryfunc>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> PyAsyncAexitProtocolImpl for T
|
impl<T> PyAsyncAexitProtocolImpl for T
|
||||||
where T: PyAsyncProtocol
|
where T: PyAsyncProtocol
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
default fn am_aexit() -> Option<ffi::unaryfunc> {
|
default fn __aexit__() -> Option<PyMethodDefType> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> PyAsyncAexitProtocolImpl for T
|
|
||||||
where T: PyAsyncAexitProtocol
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn am_aexit() -> Option<ffi::unaryfunc> {
|
|
||||||
py_unary_func_!(PyAsyncAexitProtocol, T::__aexit__, PyObjectCallbackConverter)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ pub enum PyMethodDefType {
|
||||||
pub enum PyMethodType {
|
pub enum PyMethodType {
|
||||||
PyCFunction(ffi::PyCFunction),
|
PyCFunction(ffi::PyCFunction),
|
||||||
PyCFunctionWithKeywords(ffi::PyCFunctionWithKeywords),
|
PyCFunctionWithKeywords(ffi::PyCFunctionWithKeywords),
|
||||||
|
PyNoArgsFunction(ffi::PyNoArgsFunction),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
|
@ -56,7 +57,12 @@ impl PyMethodDef {
|
||||||
unsafe {
|
unsafe {
|
||||||
::std::mem::transmute::<
|
::std::mem::transmute::<
|
||||||
ffi::PyCFunctionWithKeywords, ffi::PyCFunction>(meth)
|
ffi::PyCFunctionWithKeywords, ffi::PyCFunction>(meth)
|
||||||
}
|
},
|
||||||
|
PyMethodType::PyNoArgsFunction(meth) =>
|
||||||
|
unsafe {
|
||||||
|
::std::mem::transmute::<
|
||||||
|
ffi::PyNoArgsFunction, ffi::PyCFunction>(meth)
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
ffi::PyMethodDef {
|
ffi::PyMethodDef {
|
||||||
|
|
|
@ -193,6 +193,9 @@ fn py_class_method_defs<T>() -> Vec<ffi::PyMethodDef> {
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for def in <T as class::async::PyAsyncProtocolImpl>::methods() {
|
||||||
|
defs.push(def.as_method_def())
|
||||||
|
}
|
||||||
|
|
||||||
defs
|
defs
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue