Skip to content

stdlib.io: Implement seekable() #1173

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion tests/snippets/stdlib_io.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
from io import BufferedReader, FileIO
from io import BufferedReader, FileIO, StringIO, BytesIO
import os

fi = FileIO('README.md')
assert fi.seekable()
bb = BufferedReader(fi)
assert bb.seekable()

result = bb.read()

Expand Down
45 changes: 40 additions & 5 deletions vm/src/stdlib/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ impl PyStringIORef {
}
}

fn seekable(self, _vm: &VirtualMachine) -> bool {
true
}

//Read k bytes from the object and return.
//If k is undefined || k == -1, then we read all bytes until the end of the file.
//This also increments the stream position by the value of k
Expand Down Expand Up @@ -205,6 +209,10 @@ impl PyBytesIORef {
None => Err(vm.new_value_error("Error Performing Operation".to_string())),
}
}

fn seekable(self, _vm: &VirtualMachine) -> bool {
true
}
}

fn bytes_io_new(
Expand Down Expand Up @@ -244,7 +252,11 @@ fn io_base_cm_exit(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
}

// TODO Check if closed, then if so raise ValueError
fn io_base_flush(_zelf: PyObjectRef, _vm: &VirtualMachine) {}
fn io_base_flush(_self: PyObjectRef, _vm: &VirtualMachine) {}

fn io_base_seekable(vm: &VirtualMachine, _args: PyFuncArgs) -> PyResult {
Ok(vm.ctx.new_bool(false))
}

fn buffered_io_base_init(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(buffered, None), (raw, None)]);
Expand Down Expand Up @@ -282,6 +294,10 @@ fn buffered_reader_read(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
Ok(vm.ctx.new_bytes(result))
}

fn buffered_reader_seekable(vm: &VirtualMachine, _args: PyFuncArgs) -> PyResult {
Ok(vm.ctx.new_bool(true))
}

fn compute_c_flag(mode: &str) -> u32 {
let flags = match mode.chars().next() {
Some(mode) => match mode {
Expand Down Expand Up @@ -415,6 +431,10 @@ fn file_io_write(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
}
}

fn file_io_seekable(vm: &VirtualMachine, _args: PyFuncArgs) -> PyResult {
Ok(vm.ctx.new_bool(true))
}

fn buffered_writer_write(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(
vm,
Expand All @@ -428,6 +448,10 @@ fn buffered_writer_write(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
vm.call_method(&raw, "write", vec![obj.clone()])
}

fn buffered_writer_seekable(vm: &VirtualMachine, _args: PyFuncArgs) -> PyResult {
Ok(vm.ctx.new_bool(true))
}

fn text_io_wrapper_init(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(
vm,
Expand All @@ -439,6 +463,10 @@ fn text_io_wrapper_init(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
Ok(vm.get_none())
}

fn text_io_wrapper_seekable(vm: &VirtualMachine, _args: PyFuncArgs) -> PyResult {
Ok(vm.new_bool(true))
}

fn text_io_base_read(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(text_io_base, None)]);

Expand Down Expand Up @@ -627,6 +655,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
let io_base = py_class!(ctx, "IOBase", ctx.object(), {
"__enter__" => ctx.new_rustfunc(io_base_cm_enter),
"__exit__" => ctx.new_rustfunc(io_base_cm_exit),
"seekable" => ctx.new_rustfunc(io_base_seekable),
"flush" => ctx.new_rustfunc(io_base_flush)
});

Expand All @@ -648,7 +677,8 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
"name" => ctx.str_type(),
"read" => ctx.new_rustfunc(file_io_read),
"readinto" => ctx.new_rustfunc(file_io_readinto),
"write" => ctx.new_rustfunc(file_io_write)
"write" => ctx.new_rustfunc(file_io_write),
"seekable" => ctx.new_rustfunc(file_io_seekable)
});

// BufferedIOBase Subclasses
Expand All @@ -657,26 +687,30 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
//consistent with the python model
//For more info see: https://github.com/RustPython/RustPython/issues/547
"__init__" => ctx.new_rustfunc(buffered_io_base_init),
"read" => ctx.new_rustfunc(buffered_reader_read)
"read" => ctx.new_rustfunc(buffered_reader_read),
"seekable" => ctx.new_rustfunc(buffered_reader_seekable)
});

let buffered_writer = py_class!(ctx, "BufferedWriter", buffered_io_base.clone(), {
//workaround till the buffered classes can be fixed up to be more
//consistent with the python model
//For more info see: https://github.com/RustPython/RustPython/issues/547
"__init__" => ctx.new_rustfunc(buffered_io_base_init),
"write" => ctx.new_rustfunc(buffered_writer_write)
"write" => ctx.new_rustfunc(buffered_writer_write),
"seekable" => ctx.new_rustfunc(buffered_writer_seekable)
});

//TextIOBase Subclass
let text_io_wrapper = py_class!(ctx, "TextIOWrapper", text_io_base.clone(), {
"__init__" => ctx.new_rustfunc(text_io_wrapper_init)
"__init__" => ctx.new_rustfunc(text_io_wrapper_init),
"seekable" => ctx.new_rustfunc(text_io_wrapper_seekable)
});

//StringIO: in-memory text
let string_io = py_class!(ctx, "StringIO", text_io_base.clone(), {
"__new__" => ctx.new_rustfunc(string_io_new),
"seek" => ctx.new_rustfunc(PyStringIORef::seek),
"seekable" => ctx.new_rustfunc(PyStringIORef::seekable),
"read" => ctx.new_rustfunc(PyStringIORef::read),
"write" => ctx.new_rustfunc(PyStringIORef::write),
"getvalue" => ctx.new_rustfunc(PyStringIORef::getvalue)
Expand All @@ -688,6 +722,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
"read" => ctx.new_rustfunc(PyBytesIORef::read),
"read1" => ctx.new_rustfunc(PyBytesIORef::read),
"seek" => ctx.new_rustfunc(PyBytesIORef::seek),
"seekable" => ctx.new_rustfunc(PyBytesIORef::seekable),
"write" => ctx.new_rustfunc(PyBytesIORef::write),
"getvalue" => ctx.new_rustfunc(PyBytesIORef::getvalue)
});
Expand Down