()
| 246 | } |
| 247 | |
| 248 | fn spawn_kernel() -> io::Result<KernelProcess> { |
| 249 | let python = resolve_python_executable()?; |
| 250 | let kernel_dir = create_kernel_runtime_dir()?; |
| 251 | let kernel_path = kernel_dir.join("kernel.py"); |
| 252 | fs::write(&kernel_path, KERNEL_SOURCE)?; |
| 253 | |
| 254 | let mut command = Command::new(python); |
| 255 | command.arg(&kernel_path); |
| 256 | command.current_dir(env::current_dir()?); |
| 257 | command.stdin(Stdio::piped()); |
| 258 | command.stdout(Stdio::piped()); |
| 259 | command.stderr(Stdio::piped()); |
| 260 | command.env( |
| 261 | "CODEX_PY_TMP_DIR", |
| 262 | env::temp_dir().to_string_lossy().to_string(), |
| 263 | ); |
| 264 | if let Some(module_dirs) = resolve_python_module_dirs() { |
| 265 | command.env("CODEX_PY_REPL_PYTHON_MODULE_DIRS", module_dirs); |
| 266 | } |
| 267 | |
| 268 | let mut child = command.spawn()?; |
| 269 | let child_stdin = child |
| 270 | .stdin |
| 271 | .take() |
| 272 | .ok_or_else(|| io::Error::new(io::ErrorKind::BrokenPipe, "missing py_repl stdin"))?; |
| 273 | let child_stdout = child |
| 274 | .stdout |
| 275 | .take() |
| 276 | .ok_or_else(|| io::Error::new(io::ErrorKind::BrokenPipe, "missing py_repl stdout"))?; |
| 277 | let child_stderr = child |
| 278 | .stderr |
| 279 | .take() |
| 280 | .ok_or_else(|| io::Error::new(io::ErrorKind::BrokenPipe, "missing py_repl stderr"))?; |
| 281 | |
| 282 | let stderr_tail = Arc::new(Mutex::new(VecDeque::new())); |
| 283 | let stderr_tail_writer = Arc::clone(&stderr_tail); |
| 284 | std::thread::spawn(move || { |
| 285 | let reader = BufReader::new(child_stderr); |
| 286 | for line in reader.lines() { |
| 287 | let Ok(line) = line else { |
| 288 | break; |
| 289 | }; |
| 290 | let trimmed = line.trim(); |
| 291 | if trimmed.is_empty() { |
| 292 | continue; |
| 293 | } |
| 294 | if let Ok(mut tail) = stderr_tail_writer.lock() { |
| 295 | push_stderr_tail_line(&mut tail, trimmed); |
| 296 | } |
| 297 | } |
| 298 | }); |
| 299 | |
| 300 | Ok(KernelProcess { |
| 301 | _child: child, |
| 302 | stdin: BufWriter::new(child_stdin), |
| 303 | stdout: BufReader::new(child_stdout), |
| 304 | stderr_tail, |
| 305 | }) |
no test coverage detected