Skip to content

Commit 6767b4e

Browse files
committed
BytesIO First Pass
1 parent 2b555cb commit 6767b4e

File tree

5 files changed

+100
-27
lines changed

5 files changed

+100
-27
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ crate and webpack.
197197

198198
# Code style
199199

200-
The code style used is the default rustfmt codestyle. Please format your code accordingly.
200+
The code style used is the default [rustfmt](https://github.com/rust-lang/rustfmt) codestyle. Please format your code accordingly.
201201

202202
# Community
203203

tests/snippets/bytes_io.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
2+
from io import BytesIO
3+
4+
def test_01():
5+
bytes_string = b'Test String 1'
6+
7+
f = BytesIO()
8+
f.write(bytes_string)
9+
10+
assert f.getvalue() == bytes_string
11+
12+
def test_02():
13+
bytes_string = b'Test String 2'
14+
15+
f = BytesIO()
16+
f.write(bytes_string)
17+
18+
assert f.read() == bytes_string
19+
assert f.read() == b''
20+
assert f.getvalue() == b''
21+
22+
if __name__ == "__main__":
23+
test_01()
24+
test_02()

tests/snippets/string_io.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
2+
from io import StringIO
3+
4+
def test_01():
5+
string = 'Test String 1'
6+
f = StringIO()
7+
f.write(string)
8+
9+
assert f.getvalue() == string
10+
11+
def test_02():
12+
string = 'Test String 2'
13+
f = StringIO()
14+
f.write(string)
15+
16+
assert f.read() == string
17+
assert f.read() == ''
18+
assert f.getvalue() == ''
19+
20+
if __name__ == "__main__":
21+
test_01()
22+
test_02()

tests/snippets/test_io.py

Lines changed: 0 additions & 14 deletions
This file was deleted.

vm/src/stdlib/io.rs

Lines changed: 53 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ impl PyStringIORef {
5353
fn getvalue(self, _vm: &VirtualMachine) -> String {
5454
self.data.borrow().clone()
5555
}
56+
57+
fn read(self, _vm: &VirtualMachine) -> String {
58+
let data = self.data.borrow().clone();
59+
self.data.borrow_mut().clear();
60+
data
61+
}
5662
}
5763

5864
fn string_io_new(cls: PyClassRef, vm: &VirtualMachine) -> PyResult<PyStringIORef> {
@@ -62,15 +68,41 @@ fn string_io_new(cls: PyClassRef, vm: &VirtualMachine) -> PyResult<PyStringIORef
6268
.into_ref_with_type(vm, cls)
6369
}
6470

65-
fn bytes_io_init(vm: &VirtualMachine, _args: PyFuncArgs) -> PyResult {
66-
// TODO
67-
Ok(vm.get_none())
71+
#[derive(Debug, Default, Clone)]
72+
struct PyBytesIO {
73+
data: RefCell<Vec<u8>>,
6874
}
6975

70-
fn bytes_io_getvalue(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
71-
arg_check!(vm, args);
72-
// TODO
73-
Ok(vm.get_none())
76+
type PyBytesIORef = PyRef<PyBytesIO>;
77+
78+
impl PyValue for PyBytesIO {
79+
fn class(vm: &VirtualMachine) -> PyClassRef {
80+
vm.class("io", "BytesIO")
81+
}
82+
}
83+
84+
impl PyBytesIORef {
85+
fn write(self, data: objbytes::PyBytesRef, _vm: &VirtualMachine) {
86+
let data = data.get_value();
87+
self.data.borrow_mut().extend(data);
88+
}
89+
90+
fn getvalue(self, vm: &VirtualMachine) -> PyResult {
91+
Ok(vm.ctx.new_bytes(self.data.borrow().clone()))
92+
}
93+
94+
fn read(self, vm: &VirtualMachine) -> PyResult {
95+
let data = self.data.borrow().clone();
96+
self.data.borrow_mut().clear();
97+
Ok(vm.ctx.new_bytes(data))
98+
}
99+
}
100+
101+
fn bytes_io_new(cls: PyClassRef, vm: &VirtualMachine) -> PyResult<PyBytesIORef> {
102+
PyBytesIO {
103+
data: RefCell::new(Vec::new()),
104+
}
105+
.into_ref_with_type(vm, cls)
74106
}
75107

76108
fn io_base_cm_enter(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
@@ -420,9 +452,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
420452
// IOBase Subclasses
421453
let raw_io_base = py_class!(ctx, "RawIOBase", io_base.clone(), {});
422454

423-
let buffered_io_base = py_class!(ctx, "BufferedIOBase", io_base.clone(), {
424-
"__init__" => ctx.new_rustfunc(buffered_io_base_init)
425-
});
455+
let buffered_io_base = py_class!(ctx, "BufferedIOBase", io_base.clone(), {});
426456

427457
//TextIO Base has no public constructor
428458
let text_io_base = py_class!(ctx, "TextIOBase", io_base.clone(), {
@@ -441,10 +471,18 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
441471

442472
// BufferedIOBase Subclasses
443473
let buffered_reader = py_class!(ctx, "BufferedReader", buffered_io_base.clone(), {
474+
//workaround till the buffered classes can be fixed up to be more
475+
//consistent with the python model
476+
//For more info see: https://github.com/RustPython/RustPython/issues/547
477+
"__init__" => ctx.new_rustfunc(buffered_io_base_init),
444478
"read" => ctx.new_rustfunc(buffered_reader_read)
445479
});
446480

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

@@ -456,14 +494,17 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
456494
//StringIO: in-memory text
457495
let string_io = py_class!(ctx, "StringIO", text_io_base.clone(), {
458496
"__new__" => ctx.new_rustfunc(string_io_new),
497+
"read" => ctx.new_rustfunc(PyStringIORef::read),
459498
"write" => ctx.new_rustfunc(PyStringIORef::write),
460499
"getvalue" => ctx.new_rustfunc(PyStringIORef::getvalue)
461500
});
462501

463502
//BytesIO: in-memory bytes
464503
let bytes_io = py_class!(ctx, "BytesIO", buffered_io_base.clone(), {
465-
"__init__" => ctx.new_rustfunc(bytes_io_init),
466-
"getvalue" => ctx.new_rustfunc(bytes_io_getvalue)
504+
"__new__" => ctx.new_rustfunc(bytes_io_new),
505+
"read" => ctx.new_rustfunc(PyBytesIORef::read),
506+
"write" => ctx.new_rustfunc(PyBytesIORef::write),
507+
"getvalue" => ctx.new_rustfunc(PyBytesIORef::getvalue)
467508
});
468509

469510
py_module!(vm, "io", {

0 commit comments

Comments
 (0)