How to Have Rust Structs that Implement Classes Hold Function Pointers #2700
-
Hey all, I'm trying to be able to do something like this in Python... class Item(Generic[T]):
def __init__(
self,
value: T,
debug_fn=None,
display_fn=None,
lt_fn=None,
eq_fn=None,
) -> None:
self.__value = value
if debug_fn is None:
debug_fn = repr
if display_fn is None:
display_fn = str
if lt_fn is None:
lt_fn = operators.lt
if eq_fn is None:
eq_fn = operators.eq
self._debug_fn = debug_fn
self._display_fn = display_fn
self._lt_fn = lt_fn
self._eq_fn = eq_fn The rough idea behind the item class is it allows for GUIs using the framework to be able to display and sort the items in any way that makes sense to the developer using the items. I want to be able to have the same signature in Rust. Right now I have something that looks like this: #[pyclass]
#[derive(Debug)]
struct Item {
value: PyObject,
debug_fn: Py<PyFunction>,
display_fn: Py<PyFunction>,
lt_fn: Py<PyFunction>,
eq_fn: Py<PyFunction>,
}
#[pymethods]
impl Item {
#[new]
#[args(debug_fn = "None", display_fn = "None", lt_fn = "None", eq_fn = "None")]
fn new(
py: Python<'_>,
value: PyObject,
debug_fn: Option<Py<PyFunction>>,
display_fn: Option<Py<PyFunction>>,
lt_fn: Option<Py<PyFunction>>,
eq_fn: Option<Py<PyFunction>>,
) -> PyResult<Self> {
let debug_fn = match debug_fn {
Some(func) => Py<PyFunction>::from(func),
None => py.eval("repr", None, None)?.extract::<Py<PyFunction>>()?,
};
let display_fn = match display_fn {
... // Snipping, same as above
};
let lt_fn = match lt_fn {
Some(func) => Py<PyFunction>::from(func),
None => {
let locals = PyDict::new(py);
py.run("import operator; func = operator.lt", None, Some(locals))?;
match locals.get_item("func") {
Some(func) => func,
None => {
return Err(PyErr::new::<PyValueError, _>("Could not find function"))
}
}
.extract::<Py<PyFunction>>()?,
}
};
let eq_fn = match eq_fn {
... // Snipping, same as above.
};
Ok(Self {
value, debug_fn, display_fn, lt_fn, eq_fn,
})
}
} And when I try to initialize the class I get the following traceback when the str or repr function is added to the class:
What would be the best way to do this? |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 1 reply
-
Just use |
Beta Was this translation helpful? Give feedback.
-
Dang. I was hoping I'd be able to use types for type checking, but I'll do that in my code. |
Beta Was this translation helpful? Give feedback.
-
Cheers, thanks!
…On Fri, Oct 21, 2022, 9:00 AM Georg Brandl ***@***.***> wrote:
Yeah, with callables the most reasonable this is just "try calling it, and
handle the type error if it fails".
—
Reply to this email directly, view it on GitHub
<#2700 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAVFQOHTQSA3C6P7SDZT7NTWEK4YNANCNFSM6AAAAAARKZ6PVY>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
Beta Was this translation helpful? Give feedback.
Just use
PyAny
instead ofPyFunction
.PyFunction
represents only a fraction of things that are "callable" in Python.