(
file: PyObjectRef,
mode: Option<&str>,
opts: OpenArgs,
vm: &VirtualMachine,
)
| 5048 | } |
| 5049 | |
| 5050 | pub fn io_open( |
| 5051 | file: PyObjectRef, |
| 5052 | mode: Option<&str>, |
| 5053 | opts: OpenArgs, |
| 5054 | vm: &VirtualMachine, |
| 5055 | ) -> PyResult { |
| 5056 | // mode is optional: 'rt' is the default mode (open from reading text) |
| 5057 | let mode_string = mode.unwrap_or("r"); |
| 5058 | let mode = mode_string |
| 5059 | .parse::<Mode>() |
| 5060 | .map_err(|e| vm.new_value_error(e.error_msg(mode_string)))?; |
| 5061 | |
| 5062 | if let EncodeMode::Bytes = mode.encode { |
| 5063 | let msg = if opts.encoding.is_some() { |
| 5064 | Some("binary mode doesn't take an encoding argument") |
| 5065 | } else if opts.errors.is_some() { |
| 5066 | Some("binary mode doesn't take an errors argument") |
| 5067 | } else if opts.newline.is_some() { |
| 5068 | Some("binary mode doesn't take a newline argument") |
| 5069 | } else { |
| 5070 | None |
| 5071 | }; |
| 5072 | if let Some(msg) = msg { |
| 5073 | return Err(vm.new_value_error(msg)); |
| 5074 | } |
| 5075 | } |
| 5076 | |
| 5077 | // check file descriptor validity |
| 5078 | #[cfg(all(unix, feature = "host_env"))] |
| 5079 | if let Ok(crate::ospath::OsPathOrFd::Fd(fd)) = file.clone().try_into_value(vm) { |
| 5080 | nix::fcntl::fcntl(fd, nix::fcntl::F_GETFD).map_err(|_| vm.new_last_errno_error())?; |
| 5081 | } |
| 5082 | |
| 5083 | // Construct a RawIO (subclass of RawIOBase) |
| 5084 | // On Windows, use _WindowsConsoleIO for console handles. |
| 5085 | // This is subsequently consumed by a Buffered Class. |
| 5086 | #[cfg(all(feature = "host_env", windows))] |
| 5087 | let is_console = super::winconsoleio::pyio_get_console_type(&file, vm) != '\0'; |
| 5088 | #[cfg(not(all(feature = "host_env", windows)))] |
| 5089 | let is_console = false; |
| 5090 | |
| 5091 | let file_io_class: &Py<PyType> = { |
| 5092 | cfg_if::cfg_if! { |
| 5093 | if #[cfg(all(feature = "host_env", windows))] { |
| 5094 | if is_console { |
| 5095 | Some(super::winconsoleio::WindowsConsoleIO::static_type()) |
| 5096 | } else { |
| 5097 | Some(super::fileio::FileIO::static_type()) |
| 5098 | } |
| 5099 | } else if #[cfg(feature = "host_env")] { |
| 5100 | Some(super::fileio::FileIO::static_type()) |
| 5101 | } else { |
| 5102 | None |
| 5103 | } |
| 5104 | } |
| 5105 | } |
| 5106 | .ok_or_else(|| { |
| 5107 | new_unsupported_operation( |
no test coverage detected