iobase_finalize in Modules/_io/iobase.c
(zelf: &PyObject, vm: &VirtualMachine)
| 35 | |
| 36 | /// iobase_finalize in Modules/_io/iobase.c |
| 37 | fn iobase_finalize(zelf: &PyObject, vm: &VirtualMachine) { |
| 38 | // If `closed` doesn't exist or can't be evaluated as bool, then the |
| 39 | // object is probably in an unusable state, so ignore. |
| 40 | let closed = match vm.get_attribute_opt(zelf.to_owned(), "closed") { |
| 41 | Ok(Some(val)) => match val.try_to_bool(vm) { |
| 42 | Ok(b) => b, |
| 43 | Err(_) => return, |
| 44 | }, |
| 45 | _ => return, |
| 46 | }; |
| 47 | if !closed { |
| 48 | // Signal close() that it was called as part of the object |
| 49 | // finalization process. |
| 50 | let _ = zelf.set_attr("_finalizing", vm.ctx.true_value.clone(), vm); |
| 51 | if let Err(e) = vm.call_method(zelf, "close", ()) { |
| 52 | // BrokenPipeError during GC finalization is expected when pipe |
| 53 | // buffer objects are collected after the subprocess dies. The |
| 54 | // underlying fd is still properly closed by raw.close(). |
| 55 | // Popen.__del__ catches BrokenPipeError, but our tracing GC may |
| 56 | // finalize pipe buffers before Popen.__del__ runs. |
| 57 | if !e.fast_isinstance(vm.ctx.exceptions.broken_pipe_error) { |
| 58 | vm.run_unraisable(e, None, zelf.to_owned()); |
| 59 | } |
| 60 | } |
| 61 | } |
| 62 | } |
| 63 | |
| 64 | // not used on all platforms |
| 65 | #[derive(Copy, Clone)] |
no test coverage detected