(
task: &PyRef<PyTask>,
result: PyObjectRef,
vm: &VirtualMachine,
)
| 2115 | } |
| 2116 | |
| 2117 | fn task_step_handle_result( |
| 2118 | task: &PyRef<PyTask>, |
| 2119 | result: PyObjectRef, |
| 2120 | vm: &VirtualMachine, |
| 2121 | ) -> PyResult<()> { |
| 2122 | // Check if task awaits on itself |
| 2123 | let task_obj: PyObjectRef = task.clone().into(); |
| 2124 | if result.is(&task_obj) { |
| 2125 | let task_repr = task_obj.repr(vm)?; |
| 2126 | let msg = format!("Task cannot await on itself: {}", task_repr.as_wtf8()); |
| 2127 | task.base.fut_state.store(FutureState::Finished); |
| 2128 | *task.base.fut_exception.write() = Some(vm.new_runtime_error(msg).into()); |
| 2129 | PyTask::schedule_callbacks(task, vm)?; |
| 2130 | _unregister_task(task_obj, vm)?; |
| 2131 | return Ok(()); |
| 2132 | } |
| 2133 | |
| 2134 | let blocking = vm |
| 2135 | .get_attribute_opt( |
| 2136 | result.clone(), |
| 2137 | vm.ctx.intern_str("_asyncio_future_blocking"), |
| 2138 | )? |
| 2139 | .and_then(|v| v.try_to_bool(vm).ok()) |
| 2140 | .unwrap_or(false); |
| 2141 | |
| 2142 | if blocking { |
| 2143 | result.set_attr( |
| 2144 | vm.ctx.intern_str("_asyncio_future_blocking"), |
| 2145 | vm.ctx.new_bool(false), |
| 2146 | vm, |
| 2147 | )?; |
| 2148 | |
| 2149 | // Get the future's loop, similar to get_future_loop: |
| 2150 | // 1. If it's our native Future/Task, access fut_loop directly (check Task first) |
| 2151 | // 2. Otherwise try get_loop(), falling back to _loop on AttributeError |
| 2152 | let fut_loop = if let Ok(task) = result.clone().downcast::<PyTask>() { |
| 2153 | task.base |
| 2154 | .fut_loop |
| 2155 | .read() |
| 2156 | .clone() |
| 2157 | .unwrap_or_else(|| vm.ctx.none()) |
| 2158 | } else if let Ok(fut) = result.clone().downcast::<PyFuture>() { |
| 2159 | fut.fut_loop.read().clone().unwrap_or_else(|| vm.ctx.none()) |
| 2160 | } else { |
| 2161 | // Try get_loop(), fall back to _loop on AttributeError |
| 2162 | match vm.call_method(&result, "get_loop", ()) { |
| 2163 | Ok(loop_obj) => loop_obj, |
| 2164 | Err(e) if e.fast_isinstance(vm.ctx.exceptions.attribute_error) => { |
| 2165 | result.get_attr(vm.ctx.intern_str("_loop"), vm)? |
| 2166 | } |
| 2167 | Err(e) => return Err(e), |
| 2168 | } |
| 2169 | }; |
| 2170 | let task_loop = task.base.fut_loop.read().clone(); |
| 2171 | if let Some(task_loop) = task_loop |
| 2172 | && !fut_loop.is(&task_loop) |
| 2173 | { |
| 2174 | let task_repr = task |
no test coverage detected