Skip to content

Commit f90f58b

Browse files
committed
sys.{get,set}_asyncgen_hooks
1 parent 78fae73 commit f90f58b

File tree

2 files changed

+67
-3
lines changed

2 files changed

+67
-3
lines changed

vm/src/stdlib/sys.rs

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ mod sys {
1010
ascii,
1111
hash::{PyHash, PyUHash},
1212
},
13+
convert::ToPyObject,
1314
frame::FrameRef,
1415
function::{FuncArgs, OptionalArg, PosArgs},
15-
stdlib::builtins,
16-
stdlib::warnings::warn,
16+
stdlib::{builtins, warnings::warn},
1717
types::PyStructSequence,
1818
version,
1919
vm::{Settings, VirtualMachine},
@@ -706,6 +706,68 @@ mod sys {
706706
crate::vm::thread::COROUTINE_ORIGIN_TRACKING_DEPTH.with(|cell| cell.get()) as _
707707
}
708708

709+
#[derive(FromArgs)]
710+
struct SetAsyncgenHooksArgs {
711+
#[pyarg(any, optional)]
712+
firstiter: OptionalArg<Option<PyObjectRef>>,
713+
#[pyarg(any, optional)]
714+
finalizer: OptionalArg<Option<PyObjectRef>>,
715+
}
716+
717+
#[pyfunction]
718+
fn set_asyncgen_hooks(args: SetAsyncgenHooksArgs, vm: &VirtualMachine) -> PyResult<()> {
719+
if let Some(Some(finalizer)) = args.finalizer.as_option() {
720+
if !finalizer.is_callable() {
721+
return Err(vm.new_type_error(format!(
722+
"callable finalizer expected, got {:.50}",
723+
finalizer.class().name()
724+
)));
725+
}
726+
}
727+
728+
if let Some(Some(firstiter)) = args.firstiter.as_option() {
729+
if !firstiter.is_callable() {
730+
return Err(vm.new_type_error(format!(
731+
"callable firstiter expected, got {:.50}",
732+
firstiter.class().name()
733+
)));
734+
}
735+
}
736+
737+
if let Some(finalizer) = args.finalizer.into_option() {
738+
crate::vm::thread::ASYNC_GEN_FINALIZER.with(|cell| {
739+
cell.replace(finalizer);
740+
});
741+
}
742+
if let Some(firstiter) = args.firstiter.into_option() {
743+
crate::vm::thread::ASYNC_GEN_FIRSTITER.with(|cell| {
744+
cell.replace(firstiter);
745+
});
746+
}
747+
748+
Ok(())
749+
}
750+
751+
#[pyclass(no_attr, name = "asyncgen_hooks")]
752+
#[derive(PyStructSequence)]
753+
pub(super) struct PyAsyncgenHooks {
754+
firstiter: PyObjectRef,
755+
finalizer: PyObjectRef,
756+
}
757+
758+
#[pyclass(with(PyStructSequence))]
759+
impl PyAsyncgenHooks {}
760+
761+
#[pyfunction]
762+
fn get_asyncgen_hooks(vm: &VirtualMachine) -> PyAsyncgenHooks {
763+
PyAsyncgenHooks {
764+
firstiter: crate::vm::thread::ASYNC_GEN_FIRSTITER
765+
.with(|cell| cell.borrow().clone().to_pyobject(vm)),
766+
finalizer: crate::vm::thread::ASYNC_GEN_FINALIZER
767+
.with(|cell| cell.borrow().clone().to_pyobject(vm)),
768+
}
769+
}
770+
709771
/// sys.flags
710772
///
711773
/// Flags provided through command line arguments or environment vars.

vm/src/vm/thread.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{AsObject, PyObject, VirtualMachine};
1+
use crate::{AsObject, PyObject, PyObjectRef, VirtualMachine};
22
use itertools::Itertools;
33
use std::{
44
cell::{Cell, RefCell},
@@ -11,6 +11,8 @@ thread_local! {
1111
static VM_CURRENT: RefCell<*const VirtualMachine> = std::ptr::null::<VirtualMachine>().into();
1212

1313
pub(crate) static COROUTINE_ORIGIN_TRACKING_DEPTH: Cell<u32> = const { Cell::new(0) };
14+
pub(crate) static ASYNC_GEN_FINALIZER: RefCell<Option<PyObjectRef>> = const { RefCell::new(None) };
15+
pub(crate) static ASYNC_GEN_FIRSTITER: RefCell<Option<PyObjectRef>> = const { RefCell::new(None) };
1416
}
1517

1618
pub fn with_current_vm<R>(f: impl FnOnce(&VirtualMachine) -> R) -> R {

0 commit comments

Comments
 (0)