(&self, _value: PyObjectRef, vm: &VirtualMachine)
| 949 | impl PyFutureIter { |
| 950 | #[pymethod] |
| 951 | fn send(&self, _value: PyObjectRef, vm: &VirtualMachine) -> PyResult { |
| 952 | let future = self.future.read().clone(); |
| 953 | let future = match future { |
| 954 | Some(f) => f, |
| 955 | None => return Err(vm.new_stop_iteration(None)), |
| 956 | }; |
| 957 | |
| 958 | // Try to get blocking flag (check Task first since it inherits from Future) |
| 959 | let blocking = if let Some(task) = future.downcast_ref::<PyTask>() { |
| 960 | task.base.fut_blocking.load(Ordering::Relaxed) |
| 961 | } else if let Some(fut) = future.downcast_ref::<PyFuture>() { |
| 962 | fut.fut_blocking.load(Ordering::Relaxed) |
| 963 | } else { |
| 964 | // For non-native futures, check the attribute |
| 965 | vm.get_attribute_opt( |
| 966 | future.clone(), |
| 967 | vm.ctx.intern_str("_asyncio_future_blocking"), |
| 968 | )? |
| 969 | .map(|v| v.try_to_bool(vm)) |
| 970 | .transpose()? |
| 971 | .unwrap_or(false) |
| 972 | }; |
| 973 | |
| 974 | // Check if future is done |
| 975 | let done = vm.call_method(&future, "done", ())?; |
| 976 | if done.try_to_bool(vm)? { |
| 977 | *self.future.write() = None; |
| 978 | let result = vm.call_method(&future, "result", ())?; |
| 979 | return Err(vm.new_stop_iteration(Some(result))); |
| 980 | } |
| 981 | |
| 982 | // If still pending and blocking is already set, raise RuntimeError |
| 983 | // This means await wasn't used with future |
| 984 | if blocking { |
| 985 | return Err(vm.new_runtime_error("await wasn't used with future")); |
| 986 | } |
| 987 | |
| 988 | // First call: set blocking flag and yield the future (check Task first) |
| 989 | if let Some(task) = future.downcast_ref::<PyTask>() { |
| 990 | task.base.fut_blocking.store(true, Ordering::Relaxed); |
| 991 | } else if let Some(fut) = future.downcast_ref::<PyFuture>() { |
| 992 | fut.fut_blocking.store(true, Ordering::Relaxed); |
| 993 | } else { |
| 994 | future.set_attr( |
| 995 | vm.ctx.intern_str("_asyncio_future_blocking"), |
| 996 | vm.ctx.true_value.clone(), |
| 997 | vm, |
| 998 | )?; |
| 999 | } |
| 1000 | Ok(future) |
| 1001 | } |
| 1002 | |
| 1003 | #[pymethod] |
| 1004 | fn throw( |
no test coverage detected