-
Notifications
You must be signed in to change notification settings - Fork 770
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pymodule bound #3897
Pymodule bound #3897
Changes from 1 commit
9db0ea9
a05342e
e310b4a
b67f93f
90a1efe
4af75fe
df1da21
f7a4e82
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -126,13 +126,42 @@ macro_rules! py_run_impl { | |
macro_rules! wrap_pyfunction { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This one should now get a deprecation warning I thing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good spot! I think maybe this makes sense to do in a separate PR since it'll cause a lot of churn in tests. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Makes sense 👍 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like that is #3899 |
||
($function:path) => { | ||
&|py_or_module| { | ||
use $crate::derive_utils::PyFunctionArguments; | ||
use $function as wrapped_pyfunction; | ||
$crate::impl_::pyfunction::_wrap_pyfunction(&wrapped_pyfunction::DEF, py_or_module) | ||
let function_arguments: PyFunctionArguments<'_> = | ||
::std::convert::Into::into(py_or_module); | ||
function_arguments.wrap_pyfunction(&wrapped_pyfunction::DEF) | ||
} | ||
}; | ||
($function:path, $py_or_module:expr) => {{ | ||
use $crate::derive_utils::PyFunctionArguments; | ||
use $function as wrapped_pyfunction; | ||
$crate::impl_::pyfunction::_wrap_pyfunction(&wrapped_pyfunction::DEF, $py_or_module) | ||
let function_arguments: PyFunctionArguments<'_> = ::std::convert::Into::into($py_or_module); | ||
function_arguments.wrap_pyfunction(&wrapped_pyfunction::DEF) | ||
}}; | ||
} | ||
|
||
/// Wraps a Rust function annotated with [`#[pyfunction]`](macro@crate::pyfunction). | ||
/// | ||
/// This can be used with [`PyModule::add_function`](crate::types::PyModule::add_function) to add free | ||
/// functions to a [`PyModule`](crate::types::PyModule) - see its documentation for more information. | ||
#[macro_export] | ||
macro_rules! wrap_pyfunction_bound { | ||
($function:path) => { | ||
&|py_or_module| { | ||
use $crate::derive_utils::PyFunctionArgumentsBound; | ||
use $function as wrapped_pyfunction; | ||
let function_arguments: PyFunctionArgumentsBound<'_, '_> = | ||
::std::convert::Into::into($py_or_module); | ||
LilyFoote marked this conversation as resolved.
Show resolved
Hide resolved
|
||
function_arguments.wrap_pyfunction(&wrapped_pyfunction::DEF) | ||
} | ||
}; | ||
($function:path, $py_or_module:expr) => {{ | ||
use $crate::derive_utils::PyFunctionArgumentsBound; | ||
use $function as wrapped_pyfunction; | ||
let function_arguments: PyFunctionArgumentsBound<'_, '_> = | ||
::std::convert::Into::into($py_or_module); | ||
function_arguments.wrap_pyfunction(&wrapped_pyfunction::DEF) | ||
}}; | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,9 @@ | ||
use crate::derive_utils::PyFunctionArguments; | ||
use crate::derive_utils::{PyFunctionArguments, PyFunctionArgumentsBound}; | ||
use crate::ffi_ptr_ext::FfiPtrExt; | ||
use crate::methods::PyMethodDefDestructor; | ||
use crate::py_result_ext::PyResultExt; | ||
use crate::types::capsule::PyCapsuleMethods; | ||
use crate::types::module::PyModuleMethods; | ||
use crate::{ | ||
ffi, | ||
impl_::pymethods::{self, PyMethodDef}, | ||
|
@@ -33,17 +34,25 @@ impl PyCFunction { | |
doc: &'static str, | ||
py_or_module: PyFunctionArguments<'a>, | ||
) -> PyResult<&'a Self> { | ||
Self::new_with_keywords_bound(fun, name, doc, py_or_module).map(Bound::into_gil_ref) | ||
Self::internal_new( | ||
&PyMethodDef::cfunction_with_keywords( | ||
name, | ||
pymethods::PyCFunctionWithKeywords(fun), | ||
doc, | ||
), | ||
py_or_module, | ||
) | ||
.map(Bound::into_gil_ref) | ||
} | ||
|
||
/// Create a new built-in function with keywords (*args and/or **kwargs). | ||
pub fn new_with_keywords_bound<'a>( | ||
pub fn new_with_keywords_bound<'py>( | ||
fun: ffi::PyCFunctionWithKeywords, | ||
name: &'static str, | ||
doc: &'static str, | ||
py_or_module: PyFunctionArguments<'a>, | ||
) -> PyResult<Bound<'a, Self>> { | ||
Self::internal_new( | ||
py_or_module: PyFunctionArgumentsBound<'_, 'py>, | ||
) -> PyResult<Bound<'py, Self>> { | ||
Self::internal_new_bound( | ||
&PyMethodDef::cfunction_with_keywords( | ||
name, | ||
pymethods::PyCFunctionWithKeywords(fun), | ||
|
@@ -67,17 +76,21 @@ impl PyCFunction { | |
doc: &'static str, | ||
py_or_module: PyFunctionArguments<'a>, | ||
) -> PyResult<&'a Self> { | ||
Self::new_bound(fun, name, doc, py_or_module).map(Bound::into_gil_ref) | ||
Self::internal_new( | ||
&PyMethodDef::noargs(name, pymethods::PyCFunction(fun), doc), | ||
py_or_module, | ||
) | ||
.map(Bound::into_gil_ref) | ||
} | ||
|
||
/// Create a new built-in function which takes no arguments. | ||
pub fn new_bound<'a>( | ||
pub fn new_bound<'py>( | ||
fun: ffi::PyCFunction, | ||
name: &'static str, | ||
doc: &'static str, | ||
py_or_module: PyFunctionArguments<'a>, | ||
) -> PyResult<Bound<'a, Self>> { | ||
Self::internal_new( | ||
py_or_module: PyFunctionArgumentsBound<'_, 'py>, | ||
) -> PyResult<Bound<'py, Self>> { | ||
Self::internal_new_bound( | ||
&PyMethodDef::noargs(name, pymethods::PyCFunction(fun), doc), | ||
py_or_module, | ||
) | ||
|
@@ -189,6 +202,35 @@ impl PyCFunction { | |
.downcast_into_unchecked() | ||
} | ||
} | ||
|
||
#[doc(hidden)] | ||
pub(crate) fn internal_new_bound<'py>( | ||
method_def: &PyMethodDef, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we don't need this. We can change the signature of |
||
py_or_module: PyFunctionArgumentsBound<'_, '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() | ||
} | ||
} | ||
} | ||
|
||
fn closure_capsule_name() -> &'static CStr { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a bit sad to still need this
as_gil_ref()
call for now.