diff --git a/src/shell.rs b/src/shell.rs index e3922ee88..dafe3aaec 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -6,7 +6,7 @@ use rustpython_vm::readline::{Readline, ReadlineResult}; use rustpython_vm::{ exceptions::{print_exception, PyBaseExceptionRef}, obj::objtype, - pyobject::{ItemProtocol, PyResult}, + pyobject::PyResult, scope::Scope, VirtualMachine, }; @@ -19,19 +19,10 @@ enum ShellExecResult { fn shell_exec(vm: &VirtualMachine, source: &str, scope: Scope) -> ShellExecResult { match vm.compile(source, compile::Mode::Single, "".to_owned()) { - Ok(code) => { - match vm.run_code_obj(code, scope.clone()) { - Ok(value) => { - // Save non-None values as "_" - if !vm.is_none(&value) { - let key = "_"; - scope.globals.set_item(key, value, vm).unwrap(); - } - ShellExecResult::Ok - } - Err(err) => ShellExecResult::PyErr(err), - } - } + Ok(code) => match vm.run_code_obj(code, scope.clone()) { + Ok(_val) => ShellExecResult::Ok, + Err(err) => ShellExecResult::PyErr(err), + }, Err(CompileError { error: CompileErrorType::Parse(ParseErrorType::EOF), .. diff --git a/vm/src/builtins.rs b/vm/src/builtins.rs index d4899e0a5..1f5f08bd5 100644 --- a/vm/src/builtins.rs +++ b/vm/src/builtins.rs @@ -618,7 +618,7 @@ pub fn builtin_exit(exit_code_arg: OptionalArg, vm: &VirtualMachine Err(vm.new_exception(vm.ctx.exceptions.system_exit.clone(), vec![code])) } -#[derive(Debug, FromArgs)] +#[derive(Debug, Default, FromArgs)] pub struct PrintOptions { #[pyarg(keyword_only, default = "None")] sep: Option, diff --git a/vm/src/frame.rs b/vm/src/frame.rs index ae171410c..e522a8b4f 100644 --- a/vm/src/frame.rs +++ b/vm/src/frame.rs @@ -647,13 +647,10 @@ impl ExecutingFrame<'_> { bytecode::Instruction::Continue => self.unwind_blocks(vm, UnwindReason::Continue), bytecode::Instruction::PrintExpr => { let expr = self.pop_value(); - if !expr.is(&vm.get_none()) { - let repr = vm.to_repr(&expr)?; - // TODO: implement sys.displayhook - if let Ok(ref print) = vm.get_attribute(vm.builtins.clone(), "print") { - vm.invoke(print, vec![repr.into_object()])?; - } - } + + let displayhook = vm.get_attribute(vm.sys_module.clone(), "displayhook")?; + vm.invoke(&displayhook, vec![expr])?; + Ok(None) } bytecode::Instruction::LoadBuildClass => { diff --git a/vm/src/obj/objbool.rs b/vm/src/obj/objbool.rs index 56d21bb5c..e67a39dc2 100644 --- a/vm/src/obj/objbool.rs +++ b/vm/src/obj/objbool.rs @@ -187,7 +187,7 @@ pub fn get_py_int(obj: &PyObjectRef) -> &PyInt { &obj.payload::().unwrap() } -#[derive(Debug, Copy, Clone, PartialEq)] +#[derive(Debug, Default, Copy, Clone, PartialEq)] pub struct IntoPyBool { value: bool, } diff --git a/vm/src/sysmodule.rs b/vm/src/sysmodule.rs index 52ab87699..73d360d80 100644 --- a/vm/src/sysmodule.rs +++ b/vm/src/sysmodule.rs @@ -1,8 +1,9 @@ use std::sync::Arc; use std::{env, mem}; +use crate::builtins; use crate::frame::FrameRef; -use crate::function::OptionalArg; +use crate::function::{Args, OptionalArg, PyFuncArgs}; use crate::obj::objstr::PyStringRef; use crate::pyhash::PyHashInfo; use crate::pyobject::{ @@ -202,6 +203,24 @@ fn sys_exit(code: OptionalArg, vm: &VirtualMachine) -> PyResult { Err(vm.new_exception(vm.ctx.exceptions.system_exit.clone(), vec![code])) } +fn sys_audit(_args: PyFuncArgs) { + // TODO: sys.audit implementation +} + +fn sys_displayhook(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { + // Save non-None values as "_" + if vm.is_none(&obj) { + return Ok(()); + } + // set to none to avoid recursion while printing + vm.set_attr(&vm.builtins, "_", vm.get_none())?; + // TODO: catch encoding errors + let repr = vm.to_repr(&obj)?.into_object(); + builtins::builtin_print(Args::new(vec![repr]), Default::default(), vm)?; + vm.set_attr(&vm.builtins, "_", obj)?; + Ok(()) +} + pub fn make_module(vm: &VirtualMachine, module: PyObjectRef, builtins: PyObjectRef) { let ctx = &vm.ctx; @@ -394,6 +413,9 @@ settrace() -- set the global debug tracing function "base_exec_prefix" => ctx.new_str(base_exec_prefix.to_owned()), "exit" => ctx.new_function(sys_exit), "abiflags" => ctx.new_str("".to_owned()), + "audit" => ctx.new_function(sys_audit), + "displayhook" => ctx.new_function(sys_displayhook), + "__displayhook__" => ctx.new_function(sys_displayhook), }); modules.set_item("sys", module.clone(), vm).unwrap();