Skip to content

Commit cb90e5d

Browse files
committed
PyCallable skeetch
1 parent 9f0db9a commit cb90e5d

File tree

2 files changed

+34
-2
lines changed

2 files changed

+34
-2
lines changed

vm/src/protocol/mod.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,35 @@ pub use iter::{PyIter, PyIterIter, PyIterReturn};
1010
pub use mapping::{PyMapping, PyMappingMethods};
1111
pub use number::{PyNumber, PyNumberMethods};
1212
pub use sequence::{PySequence, PySequenceMethods};
13+
14+
use crate::function::IntoFuncArgs;
15+
use crate::types::GenericMethod;
16+
use crate::{PyObject, PyResult, VirtualMachine};
17+
18+
impl PyObject {
19+
#[inline]
20+
pub fn to_callable(&self) -> Option<PyCallable<'_>> {
21+
PyCallable::new(self)
22+
}
23+
24+
#[inline]
25+
pub fn is_callable(&self) -> bool {
26+
self.to_callable().is_some()
27+
}
28+
}
29+
30+
pub struct PyCallable<'a> {
31+
pub obj: &'a PyObject,
32+
pub call: GenericMethod,
33+
}
34+
35+
impl<'a> PyCallable<'a> {
36+
pub fn new(obj: &'a PyObject) -> Option<Self> {
37+
let call = obj.class().mro_find_map(|cls| cls.slots.call.load())?;
38+
Some(PyCallable { obj, call })
39+
}
40+
41+
pub fn invoke(&self, args: impl IntoFuncArgs, vm: &VirtualMachine) -> PyResult {
42+
(self.call)(self.obj, args.into_args(vm), vm)
43+
}
44+
}

vm/src/signal.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ fn trigger_signals(vm: &VirtualMachine) -> PyResult<()> {
3737
let triggered = trigger.swap(false, Ordering::Relaxed);
3838
if triggered {
3939
if let Some(handler) = &signal_handlers[signum] {
40-
if vm.is_callable(handler) {
41-
vm.invoke(handler, (signum, vm.ctx.none()))?;
40+
if let Some(callable) = handler.to_callable() {
41+
callable.invoke((signum, vm.ctx.none()), vm)?;
4242
}
4343
}
4444
}

0 commit comments

Comments
 (0)