Support fileno as name in FileIO

This commit is contained in:
Aviv Palivoda committed 2019-06-25 19:13:27 +03:00
1 parent 725cfcc58d
commit dc7eb24aab
2 files changed
+34 -32

No files matched your search

+7
View File
@@ -1,4 +1,5 @@
from io import BufferedReader, FileIO
import os
fi = FileIO('README.md')
bb = BufferedReader(fi)
@@ -14,3 +15,9 @@ with FileIO('README.md') as fio:
assert len(result) <= 8*1024
assert len(result) >= 0
assert isinstance(result, bytes)
fd = os.open('README.md', os.O_RDONLY)
with FileIO(fd) as fio:
res2 = fio.read()
assert res == res2
+27 -32
View File
@@ -2,9 +2,7 @@
* I/O core tools.
*/
use std::cell::RefCell;
use std::fs::File;
use std::io::prelude::*;
use std::io::BufReader;
use std::io::Cursor;
use std::io::SeekFrom;
@@ -20,6 +18,7 @@ use crate::obj::objbytearray::PyByteArray;
use crate::obj::objbytes;
use crate::obj::objint;
use crate::obj::objstr;
use crate::obj::objtype;
use crate::obj::objtype::PyClassRef;
use crate::pyobject::{BufferProtocol, PyObjectRef, PyRef, PyResult, PyValue};
use crate::vm::VirtualMachine;
@@ -305,47 +304,43 @@ fn file_io_init(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(
vm,
args,
required = [(file_io, None), (name, Some(vm.ctx.str_type()))],
required = [(file_io, None), (name, None)],
optional = [(mode, Some(vm.ctx.str_type()))]
);
let rust_mode = mode.map_or("r".to_string(), objstr::get_value);
let file_no = if objtype::isinstance(&name, &vm.ctx.str_type()) {
let rust_mode = mode.map_or("r".to_string(), objstr::get_value);
let args = vec![
name.clone(),
vm.ctx
.new_int(compute_c_flag(&rust_mode).to_bigint().unwrap()),
];
os::os_open(vm, PyFuncArgs::new(args, vec![]))?
} else if objtype::isinstance(&name, &vm.ctx.int_type()) {
name.clone()
} else {
return Err(vm.new_type_error("name parameter must be string or int".to_string()));
};
match compute_c_flag(&rust_mode).to_bigint() {
Some(os_mode) => {
let args = vec![name.clone(), vm.ctx.new_int(os_mode)];
let file_no = os::os_open(vm, PyFuncArgs::new(args, vec![]))?;
vm.set_attr(file_io, "name", name.clone())?;
vm.set_attr(file_io, "fileno", file_no)?;
vm.set_attr(file_io, "closefd", vm.new_bool(false))?;
vm.set_attr(file_io, "closed", vm.new_bool(false))?;
Ok(vm.get_none())
}
None => Err(vm.new_type_error(format!("invalid mode {}", rust_mode))),
}
vm.set_attr(file_io, "name", name.clone())?;
vm.set_attr(file_io, "fileno", file_no)?;
vm.set_attr(file_io, "closefd", vm.new_bool(false))?;
vm.set_attr(file_io, "closed", vm.new_bool(false))?;
Ok(vm.get_none())
}
fn file_io_read(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(file_io, None)]);
let py_name = vm.get_attribute(file_io.clone(), "name")?;
let f = match File::open(objstr::get_value(&py_name)) {
Ok(v) => Ok(v),
Err(_) => Err(vm.new_type_error("Error opening file".to_string())),
};
let buffer = match f {
Ok(v) => Ok(BufReader::new(v)),
Err(_) => Err(vm.new_type_error("Error reading from file".to_string())),
};
let file_no = vm.get_attribute(file_io.clone(), "fileno")?;
let raw_fd = objint::get_value(&file_no).to_i64().unwrap();
let mut handle = os::rust_file(raw_fd);
let mut bytes = vec![];
if let Ok(mut buff) = buffer {
match buff.read_to_end(&mut bytes) {
Ok(_) => {}
Err(_) => return Err(vm.new_value_error("Error reading from Buffer".to_string())),
}
match handle.read_to_end(&mut bytes) {
Ok(_) => {}
Err(_) => return Err(vm.new_value_error("Error reading from Buffer".to_string())),
}
Ok(vm.ctx.new_bytes(bytes))