Skip to content

Commit f57d2e2

Browse files
authored
Merge pull request RustPython#649 from jaroel/context-manager-open
Make IOBase a context manager
2 parents 6072954 + 8f6257b commit f57d2e2

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

tests/snippets/builtin_open.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,7 @@
44
assert 'RustPython' in fd.read()
55

66
assert_raises(FileNotFoundError, lambda: open('DoesNotExist'))
7+
8+
# Use open as a context manager
9+
with open('README.md') as fp:
10+
fp.read()

vm/src/stdlib/io.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,26 @@ fn bytes_io_getvalue(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
6060
Ok(vm.get_none())
6161
}
6262

63+
fn io_base_cm_enter(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
64+
arg_check!(vm, args, required = [(instance, None)]);
65+
Ok(instance.clone())
66+
}
67+
68+
fn io_base_cm_exit(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
69+
arg_check!(
70+
vm,
71+
args,
72+
// The context manager protocol requires these, but we don't use them
73+
required = [
74+
(_instance, None),
75+
(_exception_type, None),
76+
(_exception_value, None),
77+
(_traceback, None)
78+
]
79+
);
80+
Ok(vm.get_none())
81+
}
82+
6383
fn buffered_io_base_init(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
6484
arg_check!(vm, args, required = [(buffered, None), (raw, None)]);
6585
vm.ctx.set_attr(&buffered, "raw", raw.clone());
@@ -347,7 +367,10 @@ pub fn io_open(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
347367

348368
pub fn mk_module(ctx: &PyContext) -> PyObjectRef {
349369
//IOBase the abstract base class of the IO Module
350-
let io_base = py_class!(ctx, "IOBase", ctx.object(), {});
370+
let io_base = py_class!(ctx, "IOBase", ctx.object(), {
371+
"__enter__" => ctx.new_rustfunc(io_base_cm_enter),
372+
"__exit__" => ctx.new_rustfunc(io_base_cm_exit)
373+
});
351374

352375
// IOBase Subclasses
353376
let raw_io_base = py_class!(ctx, "RawIOBase", ctx.object(), {});

0 commit comments

Comments
 (0)