@@ -9,6 +9,7 @@ thread_local! {
99 static VM : RefCell <Option <ThreadedVirtualMachine >> = const { RefCell :: new( None ) } ;
1010}
1111
12+ #[ allow( dead_code) ]
1213pub ( crate ) fn with_vm < R > ( f : impl FnOnce ( & VirtualMachine ) -> R ) -> R {
1314 if VM_CURRENT . is_set ( ) {
1415 // We have an active VM set, so use that.
@@ -62,14 +63,15 @@ pub extern "C" fn PyEval_SaveThread() -> *mut PyThreadState {
6263
6364#[ cfg( test) ]
6465mod tests {
66+ use crate :: get_main_interpreter;
6567 use crate :: pystate:: { VM , with_vm} ;
6668 use pyo3:: prelude:: * ;
6769 use rustpython_vm:: vm:: thread:: VM_CURRENT ;
6870
6971 #[ test]
7072 fn test_new_thread ( ) {
7173 Python :: attach ( |_py| {
72- with_vm ( |vm | {
74+ with_vm ( |_vm | {
7375 assert ! (
7476 VM_CURRENT . is_set( ) ,
7577 "This thread did not have a vm attached"
@@ -78,7 +80,7 @@ mod tests {
7880
7981 std:: thread:: spawn ( move || {
8082 Python :: attach ( |_py| {
81- with_vm ( |vm | {
83+ with_vm ( |_vm | {
8284 assert ! (
8385 VM_CURRENT . is_set( ) ,
8486 "This thread did not have a vm attached"
@@ -90,4 +92,33 @@ mod tests {
9092 . unwrap ( ) ;
9193 } )
9294 }
95+
96+ #[ test]
97+ fn test_current_vm_main_thread ( ) {
98+ Python :: initialize ( ) ;
99+
100+ // Detach vm from thread, because initialize attaches one automatically.
101+ VM . with ( |vm| vm. borrow_mut ( ) . take ( ) ) ;
102+
103+ // let RustPython create a vm for this thread.
104+ let vm = get_main_interpreter ( )
105+ . as_ref ( )
106+ . unwrap ( )
107+ . enter ( |vm| vm. new_thread ( ) ) ;
108+
109+ // Attach the vm using RustPython
110+ vm. run ( |_vm| {
111+ assert ! ( VM_CURRENT . is_set( ) , "This thread should have a vm attached" ) ;
112+
113+ Python :: attach ( |_py| {
114+ with_vm ( |_vm| {
115+ assert ! ( VM_CURRENT . is_set( ) ) ;
116+ assert ! (
117+ VM . with( |vm| vm. borrow( ) . is_none( ) ) ,
118+ "We should not create a new vm when there is already a vm active"
119+ )
120+ } )
121+ } )
122+ } ) ;
123+ }
93124}
0 commit comments