Merge pull request #2686 from dalcde/closure-name-doc
Support passing name and doc to new_closure.
This commit is contained in:
commit
6766d9f93b
1
newsfragments/2686.changed.md
Normal file
1
newsfragments/2686.changed.md
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Change PyCFunction::new_closure to take name and doc arguments.
|
|
@ -108,11 +108,16 @@ impl PyCFunction {
|
||||||
/// let i = args.extract::<(i64,)>()?.0;
|
/// let i = args.extract::<(i64,)>()?.0;
|
||||||
/// Ok(i+1)
|
/// Ok(i+1)
|
||||||
/// };
|
/// };
|
||||||
/// let add_one = types::PyCFunction::new_closure(add_one, py).unwrap();
|
/// let add_one = types::PyCFunction::new_closure(py, None, None, add_one).unwrap();
|
||||||
/// py_run!(py, add_one, "assert add_one(42) == 43");
|
/// py_run!(py, add_one, "assert add_one(42) == 43");
|
||||||
/// });
|
/// });
|
||||||
/// ```
|
/// ```
|
||||||
pub fn new_closure<F, R>(f: F, py: Python<'_>) -> PyResult<&PyCFunction>
|
pub fn new_closure<'a, F, R>(
|
||||||
|
py: Python<'a>,
|
||||||
|
name: Option<&'static str>,
|
||||||
|
doc: Option<&'static str>,
|
||||||
|
f: F,
|
||||||
|
) -> PyResult<&'a PyCFunction>
|
||||||
where
|
where
|
||||||
F: Fn(&types::PyTuple, Option<&types::PyDict>) -> R + Send + 'static,
|
F: Fn(&types::PyTuple, Option<&types::PyDict>) -> R + Send + 'static,
|
||||||
R: crate::callback::IntoPyCallbackOutput<*mut ffi::PyObject>,
|
R: crate::callback::IntoPyCallbackOutput<*mut ffi::PyObject>,
|
||||||
|
@ -129,9 +134,9 @@ impl PyCFunction {
|
||||||
)?
|
)?
|
||||||
};
|
};
|
||||||
let method_def = pymethods::PyMethodDef::cfunction_with_keywords(
|
let method_def = pymethods::PyMethodDef::cfunction_with_keywords(
|
||||||
"pyo3-closure",
|
name.unwrap_or("pyo3-closure\0"),
|
||||||
pymethods::PyCFunctionWithKeywords(run_closure::<F, R>),
|
pymethods::PyCFunctionWithKeywords(run_closure::<F, R>),
|
||||||
"",
|
doc.unwrap_or("\0"),
|
||||||
);
|
);
|
||||||
Self::internal_new_from_pointers(&method_def, py, capsule.as_ptr(), std::ptr::null_mut())
|
Self::internal_new_from_pointers(&method_def, py, capsule.as_ptr(), std::ptr::null_mut())
|
||||||
}
|
}
|
||||||
|
|
|
@ -418,9 +418,12 @@ fn test_closure() {
|
||||||
Ok(res)
|
Ok(res)
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
let closure_py = PyCFunction::new_closure(f, py).unwrap();
|
let closure_py =
|
||||||
|
PyCFunction::new_closure(py, Some("test_fn"), Some("test_fn doc"), f).unwrap();
|
||||||
|
|
||||||
py_assert!(py, closure_py, "closure_py(42) == [43]");
|
py_assert!(py, closure_py, "closure_py(42) == [43]");
|
||||||
|
py_assert!(py, closure_py, "closure_py.__name__ == 'test_fn'");
|
||||||
|
py_assert!(py, closure_py, "closure_py.__doc__ == 'test_fn doc'");
|
||||||
py_assert!(
|
py_assert!(
|
||||||
py,
|
py,
|
||||||
closure_py,
|
closure_py,
|
||||||
|
@ -439,7 +442,7 @@ fn test_closure_counter() {
|
||||||
*counter += 1;
|
*counter += 1;
|
||||||
Ok(*counter)
|
Ok(*counter)
|
||||||
};
|
};
|
||||||
let counter_py = PyCFunction::new_closure(counter_fn, py).unwrap();
|
let counter_py = PyCFunction::new_closure(py, None, None, counter_fn).unwrap();
|
||||||
|
|
||||||
py_assert!(py, counter_py, "counter_py() == 1");
|
py_assert!(py, counter_py, "counter_py() == 1");
|
||||||
py_assert!(py, counter_py, "counter_py() == 2");
|
py_assert!(py, counter_py, "counter_py() == 2");
|
||||||
|
|
|
@ -10,7 +10,7 @@ fn main() {
|
||||||
println!("This is five: {:?}", ref_.len());
|
println!("This is five: {:?}", ref_.len());
|
||||||
Ok(())
|
Ok(())
|
||||||
};
|
};
|
||||||
PyCFunction::new_closure(closure_fn, py).unwrap().into()
|
PyCFunction::new_closure(py, None, None, closure_fn).unwrap().into()
|
||||||
});
|
});
|
||||||
|
|
||||||
Python::with_gil(|py| {
|
Python::with_gil(|py| {
|
||||||
|
|
|
@ -4,8 +4,8 @@ error[E0597]: `local_data` does not live long enough
|
||||||
7 | let ref_: &[u8] = &local_data;
|
7 | let ref_: &[u8] = &local_data;
|
||||||
| ^^^^^^^^^^^ borrowed value does not live long enough
|
| ^^^^^^^^^^^ borrowed value does not live long enough
|
||||||
...
|
...
|
||||||
13 | PyCFunction::new_closure(closure_fn, py).unwrap().into()
|
13 | PyCFunction::new_closure(py, None, None, closure_fn).unwrap().into()
|
||||||
| ---------------------------------------- argument requires that `local_data` is borrowed for `'static`
|
| ---------------------------------------------------- argument requires that `local_data` is borrowed for `'static`
|
||||||
14 | });
|
14 | });
|
||||||
| - `local_data` dropped here while still borrowed
|
| - `local_data` dropped here while still borrowed
|
||||||
|
|
||||||
|
@ -20,8 +20,8 @@ error[E0373]: closure may outlive the current function, but it borrows `ref_`, w
|
||||||
note: function requires argument type to outlive `'static`
|
note: function requires argument type to outlive `'static`
|
||||||
--> tests/ui/invalid_closure.rs:13:9
|
--> tests/ui/invalid_closure.rs:13:9
|
||||||
|
|
|
|
||||||
13 | PyCFunction::new_closure(closure_fn, py).unwrap().into()
|
13 | PyCFunction::new_closure(py, None, None, closure_fn).unwrap().into()
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
help: to force the closure to take ownership of `ref_` (and any other referenced variables), use the `move` keyword
|
help: to force the closure to take ownership of `ref_` (and any other referenced variables), use the `move` keyword
|
||||||
|
|
|
|
||||||
9 | let closure_fn = move |_args: &PyTuple, _kwargs: Option<&PyDict>| -> PyResult<()> {
|
9 | let closure_fn = move |_args: &PyTuple, _kwargs: Option<&PyDict>| -> PyResult<()> {
|
||||||
|
|
Loading…
Reference in a new issue