Skip to content

Commit b547389

Browse files
committed
Remaining IO open classes: TextBaseIO, TextWrapperIO
1 parent 30165f6 commit b547389

File tree

1 file changed

+57
-16
lines changed

1 file changed

+57
-16
lines changed

vm/src/stdlib/io.rs

Lines changed: 57 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -243,49 +243,87 @@ fn buffered_writer_write(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult
243243

244244
}
245245

246+
fn text_io_wrapper_init(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
247+
arg_check!(
248+
vm,
249+
args,
250+
required = [(text_io_wrapper, None), (buffer, None)]
251+
);
252+
253+
vm.ctx.set_attr(&text_io_wrapper, "buffer", buffer.clone());
254+
Ok(vm.get_none())
255+
}
256+
257+
258+
fn text_io_base_read(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
259+
arg_check!(
260+
vm,
261+
args,
262+
required = [(text_io_base, None)]
263+
);
264+
265+
let raw = vm.ctx.get_attr(&text_io_base, "buffer").unwrap();
266+
let read = vm.get_method(raw.clone(), &"read".to_string());
267+
268+
//TODO: bytes to string
269+
vm.invoke(read.unwrap(), PyFuncArgs::default())
270+
}
271+
272+
246273
pub fn io_open(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
247274
arg_check!(
248275
vm,
249276
args,
250-
required = [(file, Some(vm.ctx.str_type())), (mode, Some(vm.ctx.str_type()))]
277+
required = [(_file, Some(vm.ctx.str_type()))],
278+
optional = [(mode, Some(vm.ctx.str_type()))]
251279
);
252280

253281
let module = mk_module(&vm.ctx);
254282

255283
//mode is optional: 'rt' is the default mode (open from reading text)
256-
//To start we construct a FileIO (subclass of RawIOBase)
284+
let rust_mode = if let Some(m) = mode {
285+
objstr::get_value(m)
286+
} else {
287+
"rt".to_string()
288+
};
289+
290+
//Class objects (potentially) consumed by io.open
291+
//RawIO: FileIO
292+
//Buffered: BufferedWriter, BufferedReader
293+
//Text: TextIOWrapper
257294
let file_io_class = vm.ctx.get_attr(&module, "FileIO").unwrap();
258295
let buffered_writer_class = vm.ctx.get_attr(&module, "BufferedWriter").unwrap();
259296
let buffered_reader_class = vm.ctx.get_attr(&module, "BufferedReader").unwrap();
297+
let text_io_wrapper_class = vm.ctx.get_attr(&module, "TextIOWrapper").unwrap();
260298

261-
//instantiate raw fileio
299+
//Construct a FileIO (subclass of RawIOBase)
300+
//This is subsequently consumed by a Buffered Class.
262301
let file_io = vm.invoke(file_io_class, args.clone()).unwrap();
263302

264-
//This is subsequently consumed by a Buffered_class of type depending
265-
//operation in the mode. i.e:
266-
let rust_mode = objstr::get_value(mode);
267-
268-
// updating => PyBufferedRandom
303+
//Create Buffered class to consume FileIO. The type of buffered class depends on
304+
//the operation in the mode.
305+
//There are 3 possible classes here, each inheriting from the RawBaseIO
269306
// creating || writing || appending => BufferedWriter
270307
let buffered = if rust_mode.contains("w") {
271-
// vm.new_not_implemented_error("Writes are not yet implemented".to_string());
272308
vm.invoke(buffered_writer_class, PyFuncArgs::new(vec![file_io.clone()], vec![]))
273309
// reading => BufferedReader
274310
} else {
275311
vm.invoke(buffered_reader_class, PyFuncArgs::new(vec![file_io.clone()], vec![]))
312+
//TODO: updating => PyBufferedRandom
276313
};
277314

278-
buffered
315+
if rust_mode.contains("t") {
316+
//If the mode is text this buffer type is consumed on construction of
317+
//a TextIOWrapper which is subsequently returned.
318+
vm.invoke(text_io_wrapper_class, PyFuncArgs::new(vec![buffered.unwrap()], vec![]))
319+
} else {
279320
// If the mode is binary this Buffered class is returned directly at
280321
// this point.
281322
//For Buffered class construct "raw" IO class e.g. FileIO and pass this into corresponding field
282-
283-
//If the mode is text this buffer type is consumed on construction of
284-
//a TextIOWrapper which is subsequently returned.
285-
// Ok(vm.get_none())
323+
buffered
324+
}
286325
}
287326

288-
289327
pub fn mk_module(ctx: &PyContext) -> PyObjectRef {
290328
let py_mod = ctx.new_module(&"io".to_string(), ctx.new_scope(None));
291329
ctx.set_attr(&py_mod, "open", ctx.new_rustfunc(io_open));
@@ -301,7 +339,9 @@ pub fn mk_module(ctx: &PyContext) -> PyObjectRef {
301339
ctx.set_attr(&buffered_io_base, "__init__", ctx.new_rustfunc(buffered_io_base_init));
302340
ctx.set_attr(&py_mod, "BufferedIOBase", buffered_io_base.clone());
303341

342+
//TextIO Base has no public constructor
304343
let text_io_base = ctx.new_class("TextIOBase", io_base.clone());
344+
ctx.set_attr(&text_io_base, "read", ctx.new_rustfunc(text_io_base_read));
305345
ctx.set_attr(&py_mod, "TextIOBase", text_io_base.clone());
306346

307347
// RawBaseIO Subclasses
@@ -323,7 +363,8 @@ pub fn mk_module(ctx: &PyContext) -> PyObjectRef {
323363
ctx.set_attr(&py_mod, "BufferedWriter", buffered_writer.clone());
324364

325365
//TextIOBase Subclass
326-
let text_io_wrapper = ctx.new_class("TextIOWrapper", ctx.object());
366+
let text_io_wrapper = ctx.new_class("TextIOWrapper", text_io_base.clone());
367+
ctx.set_attr(&text_io_wrapper, "__init__", ctx.new_rustfunc(text_io_wrapper_init));
327368
ctx.set_attr(&py_mod, "TextIOWrapper", text_io_wrapper.clone());
328369

329370
// BytesIO: in-memory bytes

0 commit comments

Comments
 (0)