cleans up `PyCFunction::internal_new` (#3910)
This deduplicates some code around `PyCFunction::internal_new`
This commit is contained in:
parent
a3ad28b70c
commit
6f03a5464f
|
@ -273,7 +273,7 @@ pub fn impl_wrap_pyfunction(
|
||||||
pub fn add_to_module(module: &#krate::Bound<'_, #krate::types::PyModule>) -> #krate::PyResult<()> {
|
pub fn add_to_module(module: &#krate::Bound<'_, #krate::types::PyModule>) -> #krate::PyResult<()> {
|
||||||
use #krate::prelude::PyModuleMethods;
|
use #krate::prelude::PyModuleMethods;
|
||||||
use ::std::convert::Into;
|
use ::std::convert::Into;
|
||||||
module.add_function(#krate::types::PyCFunction::internal_new(&DEF, module.as_gil_ref().into())?)
|
module.add_function(#krate::types::PyCFunction::internal_new(module.py(), &DEF, module.into())?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
types::{PyCFunction, PyModule},
|
types::{PyCFunction, PyModule},
|
||||||
Borrowed, Bound, PyResult, Python,
|
Borrowed, Bound, PyNativeType, PyResult, Python,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use crate::impl_::pymethods::PyMethodDef;
|
pub use crate::impl_::pymethods::PyMethodDef;
|
||||||
|
@ -13,25 +13,25 @@ pub trait WrapPyFunctionArg<'py, T> {
|
||||||
|
|
||||||
impl<'py> WrapPyFunctionArg<'py, Bound<'py, PyCFunction>> for Bound<'py, PyModule> {
|
impl<'py> WrapPyFunctionArg<'py, Bound<'py, PyCFunction>> for Bound<'py, PyModule> {
|
||||||
fn wrap_pyfunction(self, method_def: &PyMethodDef) -> PyResult<Bound<'py, PyCFunction>> {
|
fn wrap_pyfunction(self, method_def: &PyMethodDef) -> PyResult<Bound<'py, PyCFunction>> {
|
||||||
PyCFunction::internal_new_bound(self.py(), method_def, Some(&self))
|
PyCFunction::internal_new(self.py(), method_def, Some(&self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'py> WrapPyFunctionArg<'py, Bound<'py, PyCFunction>> for &'_ Bound<'py, PyModule> {
|
impl<'py> WrapPyFunctionArg<'py, Bound<'py, PyCFunction>> for &'_ Bound<'py, PyModule> {
|
||||||
fn wrap_pyfunction(self, method_def: &PyMethodDef) -> PyResult<Bound<'py, PyCFunction>> {
|
fn wrap_pyfunction(self, method_def: &PyMethodDef) -> PyResult<Bound<'py, PyCFunction>> {
|
||||||
PyCFunction::internal_new_bound(self.py(), method_def, Some(self))
|
PyCFunction::internal_new(self.py(), method_def, Some(self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'py> WrapPyFunctionArg<'py, Bound<'py, PyCFunction>> for Borrowed<'_, 'py, PyModule> {
|
impl<'py> WrapPyFunctionArg<'py, Bound<'py, PyCFunction>> for Borrowed<'_, 'py, PyModule> {
|
||||||
fn wrap_pyfunction(self, method_def: &PyMethodDef) -> PyResult<Bound<'py, PyCFunction>> {
|
fn wrap_pyfunction(self, method_def: &PyMethodDef) -> PyResult<Bound<'py, PyCFunction>> {
|
||||||
PyCFunction::internal_new_bound(self.py(), method_def, Some(&self))
|
PyCFunction::internal_new(self.py(), method_def, Some(&self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'py> WrapPyFunctionArg<'py, Bound<'py, PyCFunction>> for &'_ Borrowed<'_, 'py, PyModule> {
|
impl<'py> WrapPyFunctionArg<'py, Bound<'py, PyCFunction>> for &'_ Borrowed<'_, 'py, PyModule> {
|
||||||
fn wrap_pyfunction(self, method_def: &PyMethodDef) -> PyResult<Bound<'py, PyCFunction>> {
|
fn wrap_pyfunction(self, method_def: &PyMethodDef) -> PyResult<Bound<'py, PyCFunction>> {
|
||||||
PyCFunction::internal_new_bound(self.py(), method_def, Some(self))
|
PyCFunction::internal_new(self.py(), method_def, Some(self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,13 +39,14 @@ impl<'py> WrapPyFunctionArg<'py, Bound<'py, PyCFunction>> for &'_ Borrowed<'_, '
|
||||||
// The `wrap_pyfunction_bound!` macro is needed for the Bound form.
|
// The `wrap_pyfunction_bound!` macro is needed for the Bound form.
|
||||||
impl<'py> WrapPyFunctionArg<'py, &'py PyCFunction> for Python<'py> {
|
impl<'py> WrapPyFunctionArg<'py, &'py PyCFunction> for Python<'py> {
|
||||||
fn wrap_pyfunction(self, method_def: &PyMethodDef) -> PyResult<&'py PyCFunction> {
|
fn wrap_pyfunction(self, method_def: &PyMethodDef) -> PyResult<&'py PyCFunction> {
|
||||||
PyCFunction::internal_new(method_def, self.into()).map(Bound::into_gil_ref)
|
PyCFunction::internal_new(self, method_def, None).map(Bound::into_gil_ref)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'py> WrapPyFunctionArg<'py, &'py PyCFunction> for &'py PyModule {
|
impl<'py> WrapPyFunctionArg<'py, &'py PyCFunction> for &'py PyModule {
|
||||||
fn wrap_pyfunction(self, method_def: &PyMethodDef) -> PyResult<&'py PyCFunction> {
|
fn wrap_pyfunction(self, method_def: &PyMethodDef) -> PyResult<&'py PyCFunction> {
|
||||||
PyCFunction::internal_new(method_def, self.into()).map(Bound::into_gil_ref)
|
PyCFunction::internal_new(self.py(), method_def, Some(&self.as_borrowed()))
|
||||||
|
.map(Bound::into_gil_ref)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,6 +64,6 @@ where
|
||||||
|
|
||||||
impl<'py> WrapPyFunctionArg<'py, Bound<'py, PyCFunction>> for OnlyBound<Python<'py>> {
|
impl<'py> WrapPyFunctionArg<'py, Bound<'py, PyCFunction>> for OnlyBound<Python<'py>> {
|
||||||
fn wrap_pyfunction(self, method_def: &PyMethodDef) -> PyResult<Bound<'py, PyCFunction>> {
|
fn wrap_pyfunction(self, method_def: &PyMethodDef) -> PyResult<Bound<'py, PyCFunction>> {
|
||||||
PyCFunction::internal_new_bound(self.0, method_def, None)
|
PyCFunction::internal_new(self.0, method_def, None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ use crate::{
|
||||||
impl_::pymethods::{self, PyMethodDef},
|
impl_::pymethods::{self, PyMethodDef},
|
||||||
types::{PyCapsule, PyDict, PyModule, PyString, PyTuple},
|
types::{PyCapsule, PyDict, PyModule, PyString, PyTuple},
|
||||||
};
|
};
|
||||||
use crate::{Bound, IntoPy, Py, PyAny, PyResult, Python};
|
use crate::{Bound, IntoPy, Py, PyAny, PyNativeType, PyResult, Python};
|
||||||
use std::cell::UnsafeCell;
|
use std::cell::UnsafeCell;
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
|
|
||||||
|
@ -34,13 +34,15 @@ impl PyCFunction {
|
||||||
doc: &'static str,
|
doc: &'static str,
|
||||||
py_or_module: PyFunctionArguments<'a>,
|
py_or_module: PyFunctionArguments<'a>,
|
||||||
) -> PyResult<&'a Self> {
|
) -> PyResult<&'a Self> {
|
||||||
|
let (py, module) = py_or_module.into_py_and_maybe_module();
|
||||||
Self::internal_new(
|
Self::internal_new(
|
||||||
|
py,
|
||||||
&PyMethodDef::cfunction_with_keywords(
|
&PyMethodDef::cfunction_with_keywords(
|
||||||
name,
|
name,
|
||||||
pymethods::PyCFunctionWithKeywords(fun),
|
pymethods::PyCFunctionWithKeywords(fun),
|
||||||
doc,
|
doc,
|
||||||
),
|
),
|
||||||
py_or_module,
|
module.map(PyNativeType::as_borrowed).as_deref(),
|
||||||
)
|
)
|
||||||
.map(Bound::into_gil_ref)
|
.map(Bound::into_gil_ref)
|
||||||
}
|
}
|
||||||
|
@ -53,7 +55,7 @@ impl PyCFunction {
|
||||||
doc: &'static str,
|
doc: &'static str,
|
||||||
module: Option<&Bound<'py, PyModule>>,
|
module: Option<&Bound<'py, PyModule>>,
|
||||||
) -> PyResult<Bound<'py, Self>> {
|
) -> PyResult<Bound<'py, Self>> {
|
||||||
Self::internal_new_bound(
|
Self::internal_new(
|
||||||
py,
|
py,
|
||||||
&PyMethodDef::cfunction_with_keywords(
|
&PyMethodDef::cfunction_with_keywords(
|
||||||
name,
|
name,
|
||||||
|
@ -78,9 +80,11 @@ impl PyCFunction {
|
||||||
doc: &'static str,
|
doc: &'static str,
|
||||||
py_or_module: PyFunctionArguments<'a>,
|
py_or_module: PyFunctionArguments<'a>,
|
||||||
) -> PyResult<&'a Self> {
|
) -> PyResult<&'a Self> {
|
||||||
|
let (py, module) = py_or_module.into_py_and_maybe_module();
|
||||||
Self::internal_new(
|
Self::internal_new(
|
||||||
|
py,
|
||||||
&PyMethodDef::noargs(name, pymethods::PyCFunction(fun), doc),
|
&PyMethodDef::noargs(name, pymethods::PyCFunction(fun), doc),
|
||||||
py_or_module,
|
module.map(PyNativeType::as_borrowed).as_deref(),
|
||||||
)
|
)
|
||||||
.map(Bound::into_gil_ref)
|
.map(Bound::into_gil_ref)
|
||||||
}
|
}
|
||||||
|
@ -93,7 +97,7 @@ impl PyCFunction {
|
||||||
doc: &'static str,
|
doc: &'static str,
|
||||||
module: Option<&Bound<'py, PyModule>>,
|
module: Option<&Bound<'py, PyModule>>,
|
||||||
) -> PyResult<Bound<'py, Self>> {
|
) -> PyResult<Bound<'py, Self>> {
|
||||||
Self::internal_new_bound(
|
Self::internal_new(
|
||||||
py,
|
py,
|
||||||
&PyMethodDef::noargs(name, pymethods::PyCFunction(fun), doc),
|
&PyMethodDef::noargs(name, pymethods::PyCFunction(fun), doc),
|
||||||
module,
|
module,
|
||||||
|
@ -180,35 +184,6 @@ impl PyCFunction {
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub fn internal_new<'py>(
|
pub fn internal_new<'py>(
|
||||||
method_def: &PyMethodDef,
|
|
||||||
py_or_module: PyFunctionArguments<'py>,
|
|
||||||
) -> PyResult<Bound<'py, Self>> {
|
|
||||||
let (py, module) = py_or_module.into_py_and_maybe_module();
|
|
||||||
let (mod_ptr, module_name): (_, Option<Py<PyString>>) = if let Some(m) = module {
|
|
||||||
let mod_ptr = m.as_ptr();
|
|
||||||
(mod_ptr, Some(m.name()?.into_py(py)))
|
|
||||||
} else {
|
|
||||||
(std::ptr::null_mut(), None)
|
|
||||||
};
|
|
||||||
let (def, destructor) = method_def.as_method_def()?;
|
|
||||||
|
|
||||||
// FIXME: stop leaking the def and destructor
|
|
||||||
let def = Box::into_raw(Box::new(def));
|
|
||||||
std::mem::forget(destructor);
|
|
||||||
|
|
||||||
let module_name_ptr = module_name
|
|
||||||
.as_ref()
|
|
||||||
.map_or(std::ptr::null_mut(), Py::as_ptr);
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
ffi::PyCFunction_NewEx(def, mod_ptr, module_name_ptr)
|
|
||||||
.assume_owned_or_err(py)
|
|
||||||
.downcast_into_unchecked()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub(crate) fn internal_new_bound<'py>(
|
|
||||||
py: Python<'py>,
|
py: Python<'py>,
|
||||||
method_def: &PyMethodDef,
|
method_def: &PyMethodDef,
|
||||||
module: Option<&Bound<'py, PyModule>>,
|
module: Option<&Bound<'py, PyModule>>,
|
||||||
|
|
Loading…
Reference in New Issue