Skip to content

Commit 505341d

Browse files
committed
print() to sys.stdout if it's not actually stdout
1 parent f7e1d1c commit 505341d

File tree

1 file changed

+14
-44
lines changed

1 file changed

+14
-44
lines changed

vm/src/builtins.rs

Lines changed: 14 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
55
use std::cell::Cell;
66
use std::char;
7-
use std::io::{self, Write};
87
use std::str;
98

109
use num_bigint::Sign;
@@ -607,6 +606,11 @@ fn builtin_pow(
607606
}
608607
}
609608

609+
pub fn builtin_exit(exit_code_arg: OptionalArg<PyObjectRef>, vm: &VirtualMachine) -> PyResult {
610+
let code = exit_code_arg.unwrap_or_else(|| vm.new_int(0));
611+
Err(vm.new_exception(vm.ctx.exceptions.system_exit.clone(), vec![code]))
612+
}
613+
610614
#[derive(Debug, FromArgs)]
611615
pub struct PrintOptions {
612616
#[pyarg(keyword_only, default = "None")]
@@ -619,48 +623,14 @@ pub struct PrintOptions {
619623
file: Option<PyObjectRef>,
620624
}
621625

622-
trait Printer {
623-
fn write(&mut self, vm: &VirtualMachine, obj: PyStringRef) -> PyResult<()>;
624-
fn flush(&mut self, vm: &VirtualMachine) -> PyResult<()>;
625-
}
626-
627-
impl Printer for &'_ PyObjectRef {
628-
fn write(&mut self, vm: &VirtualMachine, obj: PyStringRef) -> PyResult<()> {
629-
vm.call_method(self, "write", vec![obj.into_object()])?;
630-
Ok(())
631-
}
632-
633-
fn flush(&mut self, vm: &VirtualMachine) -> PyResult<()> {
634-
vm.call_method(self, "flush", vec![])?;
635-
Ok(())
636-
}
637-
}
638-
639-
impl Printer for std::io::StdoutLock<'_> {
640-
fn write(&mut self, _vm: &VirtualMachine, s: PyStringRef) -> PyResult<()> {
641-
write!(self, "{}", s).unwrap();
642-
Ok(())
643-
}
644-
645-
fn flush(&mut self, _vm: &VirtualMachine) -> PyResult<()> {
646-
<Self as io::Write>::flush(self).unwrap();
647-
Ok(())
648-
}
649-
}
650-
651-
pub fn builtin_exit(exit_code_arg: OptionalArg<PyObjectRef>, vm: &VirtualMachine) -> PyResult {
652-
let code = exit_code_arg.unwrap_or_else(|| vm.new_int(0));
653-
Err(vm.new_exception(vm.ctx.exceptions.system_exit.clone(), vec![code]))
654-
}
655-
656626
pub fn builtin_print(objects: Args, options: PrintOptions, vm: &VirtualMachine) -> PyResult<()> {
657-
let stdout = io::stdout();
627+
// Trick so that we don't have to allocate to have a trait object
658628

659-
let mut printer: Box<dyn Printer> = if let Some(file) = &options.file {
660-
Box::new(file)
661-
} else {
662-
Box::new(stdout.lock())
629+
let file = match options.file {
630+
Some(f) => f,
631+
None => vm.get_attribute(vm.sys_module.clone(), "stdout")?,
663632
};
633+
let write = |obj: PyStringRef| vm.call_method(&file, "write", vec![obj.into_object()]);
664634

665635
let sep = options
666636
.sep
@@ -671,19 +641,19 @@ pub fn builtin_print(objects: Args, options: PrintOptions, vm: &VirtualMachine)
671641
if first {
672642
first = false;
673643
} else {
674-
printer.write(vm, sep.clone())?;
644+
write(sep.clone())?;
675645
}
676646

677-
printer.write(vm, vm.to_str(&object)?)?;
647+
write(vm.to_str(&object)?)?;
678648
}
679649

680650
let end = options
681651
.end
682652
.unwrap_or_else(|| PyString::from("\n").into_ref(vm));
683-
printer.write(vm, end)?;
653+
write(end)?;
684654

685655
if options.flush.to_bool() {
686-
printer.flush(vm)?;
656+
vm.call_method(&file, "flush", vec![])?;
687657
}
688658

689659
Ok(())

0 commit comments

Comments
 (0)