From 7bc10da1549997fd479893b18aae3ce58b232f20 Mon Sep 17 00:00:00 2001 From: jfh Date: Sun, 17 Oct 2021 10:17:49 +0300 Subject: [PATCH] Relocate vm.get_attribute to obj.get_attr. --- src/lib.rs | 14 +++++---- src/shell.rs | 4 ++- src/shell/helper.rs | 2 +- stdlib/src/array.rs | 2 +- stdlib/src/dis.rs | 2 +- stdlib/src/json.rs | 16 +++++----- stdlib/src/unicodedata.rs | 6 ++-- vm/src/builtins/function.rs | 15 ++++----- vm/src/builtins/function/jitfunc.rs | 3 +- vm/src/builtins/genericalias.rs | 7 +++-- vm/src/builtins/iter.rs | 4 +-- vm/src/builtins/module.rs | 2 +- vm/src/builtins/object.rs | 7 +++-- vm/src/builtins/pysuper.rs | 2 +- vm/src/builtins/weakproxy.rs | 2 +- vm/src/codecs.rs | 24 +++++++------- vm/src/exceptions.rs | 2 +- vm/src/format.rs | 2 +- vm/src/frame.rs | 20 +++++++----- vm/src/import.rs | 14 ++++----- vm/src/protocol/object.rs | 12 +++++-- vm/src/pyobjectrc.rs | 2 +- vm/src/scope.rs | 2 +- vm/src/stdlib/ast.rs | 3 +- vm/src/stdlib/builtins.rs | 4 +-- vm/src/stdlib/codecs.rs | 2 +- vm/src/stdlib/imp.rs | 4 +-- vm/src/stdlib/io.rs | 25 ++++++++------- vm/src/stdlib/operator.rs | 6 ++-- vm/src/stdlib/os.rs | 4 +-- vm/src/stdlib/signal.rs | 5 +-- vm/src/stdlib/sre.rs | 4 +-- vm/src/stdlib/sys.rs | 12 +++++-- vm/src/stdlib/winapi.rs | 6 ++-- vm/src/vm.rs | 49 +++++++++++------------------ wasm/lib/src/vm_class.rs | 8 ++--- 36 files changed, 158 insertions(+), 140 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 3655ffd6cc..f801e36c93 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -551,7 +551,9 @@ fn setup_main_module(vm: &VirtualMachine) -> PyResult { }) .expect("Failed to initialize __main__.__annotations__"); - vm.get_attribute(vm.sys_module.clone(), "modules")? + vm.sys_module + .clone() + .get_attr("modules", vm)? .set_item("__main__", main_module, vm)?; Ok(scope) @@ -626,19 +628,19 @@ fn run_command(vm: &VirtualMachine, scope: Scope, source: String) -> PyResult<() fn run_module(vm: &VirtualMachine, module: &str) -> PyResult<()> { debug!("Running module {}", module); let runpy = vm.import("runpy", None, 0)?; - let run_module_as_main = vm.get_attribute(runpy, "_run_module_as_main")?; + let run_module_as_main = runpy.get_attr("_run_module_as_main", vm)?; vm.invoke(&run_module_as_main, (module,))?; Ok(()) } fn get_importer(path: &str, vm: &VirtualMachine) -> PyResult> { - let path_importer_cache = vm.get_attribute(vm.sys_module.clone(), "path_importer_cache")?; + let path_importer_cache = vm.sys_module.clone().get_attr("path_importer_cache", vm)?; let path_importer_cache = PyDictRef::try_from_object(vm, path_importer_cache)?; if let Some(importer) = path_importer_cache.get_item_option(path, vm)? { return Ok(Some(importer)); } let path = vm.ctx.new_str(path); - let path_hooks = vm.get_attribute(vm.sys_module.clone(), "path_hooks")?; + let path_hooks = vm.sys_module.clone().get_attr("path_hooks", vm)?; let mut importer = None; let path_hooks: Vec = vm.extract_elements(&path_hooks)?; for path_hook in path_hooks { @@ -660,7 +662,7 @@ fn get_importer(path: &str, vm: &VirtualMachine) -> PyResult } fn insert_sys_path(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<()> { - let sys_path = vm.get_attribute(vm.sys_module.clone(), "path").unwrap(); + let sys_path = vm.sys_module.clone().get_attr("path", vm).unwrap(); vm.call_method(&sys_path, "insert", (0, obj))?; Ok(()) } @@ -670,7 +672,7 @@ fn run_script(vm: &VirtualMachine, scope: Scope, script_file: &str) -> PyResult< if get_importer(script_file, vm)?.is_some() { insert_sys_path(vm, vm.ctx.new_str(script_file).into())?; let runpy = vm.import("runpy", None, 0)?; - let run_module_as_main = vm.get_attribute(runpy, "_run_module_as_main")?; + let run_module_as_main = runpy.get_attr("_run_module_as_main", vm)?; vm.invoke(&run_module_as_main, (vm.ctx.new_str("__main__"), false))?; return Ok(()); } diff --git a/src/shell.rs b/src/shell.rs index f112f30844..e605c21154 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -56,7 +56,9 @@ pub fn run_shell(vm: &VirtualMachine, scope: Scope) -> PyResult<()> { loop { let prompt_name = if continuing { "ps2" } else { "ps1" }; let prompt = vm - .get_attribute(vm.sys_module.clone(), prompt_name) + .sys_module + .clone() + .get_attr(prompt_name, vm) .and_then(|prompt| vm.to_str(&prompt)); let prompt = match prompt { Ok(ref s) => s.as_str(), diff --git a/src/shell/helper.rs b/src/shell/helper.rs index a5afcbe281..9bcdf82c05 100644 --- a/src/shell/helper.rs +++ b/src/shell/helper.rs @@ -79,7 +79,7 @@ impl<'vm> ShellHelper<'vm> { .ok()??; for attr in parents { - current = self.vm.get_attribute(current.clone(), attr.as_str()).ok()?; + current = current.clone().get_attr(attr.as_str(), self.vm).ok()?; } let current_iter = str_iter_method(current, "__dir__").ok()?; diff --git a/stdlib/src/array.rs b/stdlib/src/array.rs index bd5837dce9..1434983032 100644 --- a/stdlib/src/array.rs +++ b/stdlib/src/array.rs @@ -1134,7 +1134,7 @@ mod array { let code = MachineFormatCode::from_typecode(array.typecode()).unwrap(); let code = PyInt::from(u8::from(code)).into_object(vm); let module = vm.import("array", None, 0)?; - let func = vm.get_attribute(module, "_array_reconstructor")?; + let func = module.get_attr("_array_reconstructor", vm)?; Ok(( func, vm.new_tuple((cls, typecode, code, bytes)), diff --git a/stdlib/src/dis.rs b/stdlib/src/dis.rs index 8e56e67385..56b7546b78 100644 --- a/stdlib/src/dis.rs +++ b/stdlib/src/dis.rs @@ -10,7 +10,7 @@ mod decl { #[pyfunction] fn dis(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { - let co = if let Ok(co) = vm.get_attribute(obj.clone(), "__code__") { + let co = if let Ok(co) = obj.clone().get_attr("__code__", vm) { // Method or function: PyRef::try_from_object(vm, co)? } else if let Ok(co_str) = PyStrRef::try_from_object(vm, obj.clone()) { diff --git a/stdlib/src/json.rs b/stdlib/src/json.rs index d91b08e782..319f192329 100644 --- a/stdlib/src/json.rs +++ b/stdlib/src/json.rs @@ -31,24 +31,24 @@ mod _json { type Args = PyObjectRef; fn py_new(cls: PyTypeRef, ctx: Self::Args, vm: &VirtualMachine) -> PyResult { - let strict = vm.get_attribute(ctx.clone(), "strict")?.try_to_bool(vm)?; - let object_hook = vm.option_if_none(vm.get_attribute(ctx.clone(), "object_hook")?); + let strict = ctx.clone().get_attr("strict", vm)?.try_to_bool(vm)?; + let object_hook = vm.option_if_none(ctx.clone().get_attr("object_hook", vm)?); let object_pairs_hook = - vm.option_if_none(vm.get_attribute(ctx.clone(), "object_pairs_hook")?); - let parse_float = vm.get_attribute(ctx.clone(), "parse_float")?; + vm.option_if_none(ctx.clone().get_attr("object_pairs_hook", vm)?); + let parse_float = ctx.clone().get_attr("parse_float", vm)?; let parse_float = if vm.is_none(&parse_float) || parse_float.is(&vm.ctx.types.float_type) { None } else { Some(parse_float) }; - let parse_int = vm.get_attribute(ctx.clone(), "parse_int")?; + let parse_int = ctx.clone().get_attr("parse_int", vm)?; let parse_int = if vm.is_none(&parse_int) || parse_int.is(&vm.ctx.types.int_type) { None } else { Some(parse_int) }; - let parse_constant = vm.get_attribute(ctx.clone(), "parse_constant")?; + let parse_constant = ctx.clone().get_attr("parse_constant", vm)?; Self { strict, @@ -89,7 +89,7 @@ mod _json { } '{' => { // TODO: parse the object in rust - let parse_obj = vm.get_attribute(self.ctx.clone(), "parse_object")?; + let parse_obj = self.ctx.clone().get_attr("parse_object", vm)?; return PyIterReturn::from_pyresult( vm.invoke( &parse_obj, @@ -106,7 +106,7 @@ mod _json { } '[' => { // TODO: parse the array in rust - let parse_array = vm.get_attribute(self.ctx.clone(), "parse_array")?; + let parse_array = self.ctx.clone().get_attr("parse_array", vm)?; return PyIterReturn::from_pyresult( vm.invoke(&parse_array, ((pystr, next_idx), scan_once)), vm, diff --git a/stdlib/src/unicodedata.rs b/stdlib/src/unicodedata.rs index ad3604c97d..8846da293b 100644 --- a/stdlib/src/unicodedata.rs +++ b/stdlib/src/unicodedata.rs @@ -6,14 +6,16 @@ use crate::vm::{PyObjectRef, PyValue, VirtualMachine}; pub fn make_module(vm: &VirtualMachine) -> PyObjectRef { let module = unicodedata::make_module(vm); - let ucd = unicodedata::Ucd::new(unic_ucd_age::UNICODE_VERSION).into_ref(vm); + let ucd: PyObjectRef = unicodedata::Ucd::new(unic_ucd_age::UNICODE_VERSION) + .into_ref(vm) + .into(); for attr in ["category", "lookup", "name", "bidirectional", "normalize"] .iter() .copied() { crate::vm::extend_module!(vm, &module, { - attr => vm.get_attribute(ucd.clone().into(), attr).unwrap(), + attr => ucd.clone().get_attr(attr, vm).unwrap(), }); } diff --git a/vm/src/builtins/function.rs b/vm/src/builtins/function.rs index d8ceaaeafe..81d429dda0 100644 --- a/vm/src/builtins/function.rs +++ b/vm/src/builtins/function.rs @@ -377,8 +377,10 @@ impl PyFunction { #[pymethod(magic)] fn repr(zelf: PyRef, vm: &VirtualMachine) -> String { - let qualname = vm - .get_attribute(zelf.as_object().clone(), "__qualname__") + let qualname = zelf + .as_object() + .clone() + .get_attr("__qualname__", vm) .ok() .and_then(|qualname_attr| qualname_attr.downcast::().ok()) .map(|qualname| qualname.as_str().to_owned()) @@ -462,7 +464,7 @@ impl GetAttr for PyBoundMethod { if let Some(obj) = zelf.get_class_attr(name.as_str()) { return vm.call_if_get_descriptor(obj, zelf.into()); } - vm.get_attribute(zelf.function.clone(), name) + zelf.function.clone().get_attr(name, vm) } } @@ -520,7 +522,7 @@ impl PyBoundMethod { #[pyproperty(magic)] fn doc(&self, vm: &VirtualMachine) -> PyResult { - vm.get_attribute(self.function.clone(), "__doc__") + self.function.clone().get_attr("__doc__", vm) } #[pyproperty(magic)] @@ -535,7 +537,7 @@ impl PyBoundMethod { #[pyproperty(magic)] fn module(&self, vm: &VirtualMachine) -> Option { - vm.get_attribute(self.function.clone(), "__module__").ok() + self.function.clone().get_attr("__module__", vm).ok() } #[pyproperty(magic)] @@ -557,8 +559,7 @@ impl PyBoundMethod { )) .into()); } - - vm.get_attribute(self.function.clone(), "__qualname__") + self.function.clone().get_attr("__qualname__", vm) } } diff --git a/vm/src/builtins/function/jitfunc.rs b/vm/src/builtins/function/jitfunc.rs index 1b0c2d3da7..8cb972fb27 100644 --- a/vm/src/builtins/function/jitfunc.rs +++ b/vm/src/builtins/function/jitfunc.rs @@ -81,7 +81,8 @@ pub fn get_jit_arg_types(func: &PyRef, vm: &VirtualMachine) -> PyRes return Ok(Vec::new()); } - let annotations = vm.get_attribute(func.clone().into(), "__annotations__")?; + let func_obj: PyObjectRef = func.clone().into(); + let annotations = func_obj.get_attr("__annotations__", vm)?; if vm.is_none(&annotations) { Err(new_jit_error( "Jitting function requires arguments to have annotations".to_owned(), diff --git a/vm/src/builtins/genericalias.rs b/vm/src/builtins/genericalias.rs index 743b1618d4..7b017df166 100644 --- a/vm/src/builtins/genericalias.rs +++ b/vm/src/builtins/genericalias.rs @@ -150,8 +150,9 @@ fn make_parameters(args: &PyTupleRef, vm: &VirtualMachine) -> PyTupleRef { for arg in args.as_slice() { if is_typevar(arg.clone()) { parameters.push(arg.clone()); - } else if let Ok(tuple) = vm - .get_attribute(arg.clone(), "__parameters__") + } else if let Ok(tuple) = arg + .clone() + .get_attr("__parameters__", vm) .and_then(|obj| PyTupleRef::try_from_object(vm, obj)) { for subparam in tuple.as_slice() { @@ -177,7 +178,7 @@ impl GetAttr for PyGenericAlias { return vm.generic_getattribute(zelf.as_object().clone(), attr); } } - vm.get_attribute(zelf.origin(), attr) + zelf.origin().get_attr(attr, vm) } } diff --git a/vm/src/builtins/iter.rs b/vm/src/builtins/iter.rs index 36d425a1ec..30f410c081 100644 --- a/vm/src/builtins/iter.rs +++ b/vm/src/builtins/iter.rs @@ -147,14 +147,14 @@ pub fn builtins_iter(vm: &VirtualMachine) -> &PyObjectRef { static_cell! { static INSTANCE: PyObjectRef; } - INSTANCE.get_or_init(|| vm.get_attribute(vm.builtins.clone(), "iter").unwrap()) + INSTANCE.get_or_init(|| vm.builtins.clone().get_attr("iter", vm).unwrap()) } pub fn builtins_reversed(vm: &VirtualMachine) -> &PyObjectRef { static_cell! { static INSTANCE: PyObjectRef; } - INSTANCE.get_or_init(|| vm.get_attribute(vm.builtins.clone(), "reversed").unwrap()) + INSTANCE.get_or_init(|| vm.builtins.clone().get_attr("reversed", vm).unwrap()) } #[pyclass(module = false, name = "iterator")] diff --git a/vm/src/builtins/module.rs b/vm/src/builtins/module.rs index d76ad2d532..1790b2b861 100644 --- a/vm/src/builtins/module.rs +++ b/vm/src/builtins/module.rs @@ -79,7 +79,7 @@ impl PyModule { #[pymethod(magic)] fn repr(zelf: PyRef, vm: &VirtualMachine) -> PyResult { let importlib = vm.import("_frozen_importlib", None, 0)?; - let module_repr = vm.get_attribute(importlib, "_module_repr")?; + let module_repr = importlib.get_attr("_module_repr", vm)?; vm.invoke(&module_repr, (zelf,)) } diff --git a/vm/src/builtins/object.rs b/vm/src/builtins/object.rs index f7116c2d2e..0b0f034e83 100644 --- a/vm/src/builtins/object.rs +++ b/vm/src/builtins/object.rs @@ -286,7 +286,8 @@ impl PyBaseObject { fn reduce_ex(obj: PyObjectRef, proto: usize, vm: &VirtualMachine) -> PyResult { if let Some(reduce) = vm.get_attribute_opt(obj.clone(), "__reduce__")? { let object_reduce = vm.ctx.types.object_type.get_attr("__reduce__").unwrap(); - let class_reduce = vm.get_attribute(obj.clone_class().into(), "__reduce__")?; + let typ_obj: PyObjectRef = obj.clone_class().into(); + let class_reduce = typ_obj.get_attr("__reduce__", vm)?; if !class_reduce.is(&object_reduce) { return vm.invoke(&reduce, ()); } @@ -364,11 +365,11 @@ pub fn init(ctx: &PyContext) { fn common_reduce(obj: PyObjectRef, proto: usize, vm: &VirtualMachine) -> PyResult { if proto >= 2 { let reducelib = vm.import("__reducelib", None, 0)?; - let reduce_2 = vm.get_attribute(reducelib, "reduce_2")?; + let reduce_2 = reducelib.get_attr("reduce_2", vm)?; vm.invoke(&reduce_2, (obj,)) } else { let copyreg = vm.import("copyreg", None, 0)?; - let reduce_ex = vm.get_attribute(copyreg, "_reduce_ex")?; + let reduce_ex = copyreg.get_attr("_reduce_ex", vm)?; vm.invoke(&reduce_ex, (obj, proto)) } } diff --git a/vm/src/builtins/pysuper.rs b/vm/src/builtins/pysuper.rs index 6985e5c5a6..35db65f521 100644 --- a/vm/src/builtins/pysuper.rs +++ b/vm/src/builtins/pysuper.rs @@ -186,7 +186,7 @@ fn supercheck(ty: PyTypeRef, obj: PyObjectRef, vm: &VirtualMachine) -> PyResult< if obj.isinstance(&ty) { return Ok(obj.clone_class()); } - let class_attr = vm.get_attribute(obj, "__class__")?; + let class_attr = obj.get_attr("__class__", vm)?; if let Ok(cls) = class_attr.downcast::() { if !cls.is(&ty) && cls.issubclass(&ty) { return Ok(cls); diff --git a/vm/src/builtins/weakproxy.rs b/vm/src/builtins/weakproxy.rs index f1e6de9621..129d752809 100644 --- a/vm/src/builtins/weakproxy.rs +++ b/vm/src/builtins/weakproxy.rs @@ -54,7 +54,7 @@ impl PyWeakProxy { "weakly-referenced object no longer exists".to_owned(), ) })?; - vm.get_attribute(obj, attr_name) + obj.get_attr(attr_name, vm) } } diff --git a/vm/src/codecs.rs b/vm/src/codecs.rs index 1417c36789..bc5e7d64ab 100644 --- a/vm/src/codecs.rs +++ b/vm/src/codecs.rs @@ -333,9 +333,9 @@ fn normalize_encoding_name(encoding: &str) -> Cow<'_, str> { // TODO: exceptions with custom payloads fn extract_unicode_error_range(err: &PyObjectRef, vm: &VirtualMachine) -> PyResult> { - let start = vm.get_attribute(err.clone(), "start")?; + let start = err.clone().get_attr("start", vm)?; let start = start.try_into_value(vm)?; - let end = vm.get_attribute(err.clone(), "end")?; + let end = err.clone().get_attr("end", vm)?; let end = end.try_into_value(vm)?; Ok(Range { start, end }) } @@ -396,7 +396,7 @@ fn xmlcharrefreplace_errors(err: PyObjectRef, vm: &VirtualMachine) -> PyResult<( return Err(bad_err_type(err, vm)); } let range = extract_unicode_error_range(&err, vm)?; - let s = PyStrRef::try_from_object(vm, vm.get_attribute(err, "object")?)?; + let s = PyStrRef::try_from_object(vm, err.get_attr("object", vm)?)?; let s_after_start = crate::common::str::try_get_chars(s.as_str(), range.start..).unwrap_or(""); let num_chars = range.len(); // capacity rough guess; assuming that the codepoints are 3 digits in decimal + the &#; @@ -411,7 +411,7 @@ fn xmlcharrefreplace_errors(err: PyObjectRef, vm: &VirtualMachine) -> PyResult<( fn backslashreplace_errors(err: PyObjectRef, vm: &VirtualMachine) -> PyResult<(String, usize)> { if is_decode_err(&err, vm) { let range = extract_unicode_error_range(&err, vm)?; - let b = PyBytesRef::try_from_object(vm, vm.get_attribute(err, "object")?)?; + let b = PyBytesRef::try_from_object(vm, err.get_attr("object", vm)?)?; let mut replace = String::with_capacity(4 * range.len()); for &c in &b[range.clone()] { use std::fmt::Write; @@ -422,7 +422,7 @@ fn backslashreplace_errors(err: PyObjectRef, vm: &VirtualMachine) -> PyResult<(S return Err(bad_err_type(err, vm)); } let range = extract_unicode_error_range(&err, vm)?; - let s = PyStrRef::try_from_object(vm, vm.get_attribute(err, "object")?)?; + let s = PyStrRef::try_from_object(vm, err.get_attr("object", vm)?)?; let s_after_start = crate::common::str::try_get_chars(s.as_str(), range.start..).unwrap_or(""); let num_chars = range.len(); // minimum 4 output bytes per char: \xNN @@ -444,7 +444,7 @@ fn backslashreplace_errors(err: PyObjectRef, vm: &VirtualMachine) -> PyResult<(S fn namereplace_errors(err: PyObjectRef, vm: &VirtualMachine) -> PyResult<(String, usize)> { if err.isinstance(&vm.ctx.exceptions.unicode_encode_error) { let range = extract_unicode_error_range(&err, vm)?; - let s = PyStrRef::try_from_object(vm, vm.get_attribute(err, "object")?)?; + let s = PyStrRef::try_from_object(vm, err.get_attr("object", vm)?)?; let s_after_start = crate::common::str::try_get_chars(s.as_str(), range.start..).unwrap_or(""); let num_chars = range.len(); @@ -539,8 +539,8 @@ fn get_standard_encoding(encoding: &str) -> (usize, StandardEncoding) { fn surrogatepass_errors(err: PyObjectRef, vm: &VirtualMachine) -> PyResult<(String, usize)> { if err.isinstance(&vm.ctx.exceptions.unicode_encode_error) { let range = extract_unicode_error_range(&err, vm)?; - let s = PyStrRef::try_from_object(vm, vm.get_attribute(err.clone(), "object")?)?; - let s_encoding = PyStrRef::try_from_object(vm, vm.get_attribute(err.clone(), "encoding")?)?; + let s = PyStrRef::try_from_object(vm, err.clone().get_attr("object", vm)?)?; + let s_encoding = PyStrRef::try_from_object(vm, err.clone().get_attr("encoding", vm)?)?; let (_, standard_encoding) = get_standard_encoding(s_encoding.as_str()); if let StandardEncoding::Unknown = standard_encoding { // Not supported, fail with original exception @@ -590,8 +590,8 @@ fn surrogatepass_errors(err: PyObjectRef, vm: &VirtualMachine) -> PyResult<(Stri Ok((out, range.end)) } else if is_decode_err(&err, vm) { let range = extract_unicode_error_range(&err, vm)?; - let s = PyStrRef::try_from_object(vm, vm.get_attribute(err.clone(), "object")?)?; - let s_encoding = PyStrRef::try_from_object(vm, vm.get_attribute(err.clone(), "encoding")?)?; + let s = PyStrRef::try_from_object(vm, err.clone().get_attr("object", vm)?)?; + let s_encoding = PyStrRef::try_from_object(vm, err.clone().get_attr("encoding", vm)?)?; let (byte_length, standard_encoding) = get_standard_encoding(s_encoding.as_str()); if let StandardEncoding::Unknown = standard_encoding { // Not supported, fail with original exception @@ -652,7 +652,7 @@ fn surrogatepass_errors(err: PyObjectRef, vm: &VirtualMachine) -> PyResult<(Stri fn surrogateescape_errors(err: PyObjectRef, vm: &VirtualMachine) -> PyResult<(String, usize)> { if err.isinstance(&vm.ctx.exceptions.unicode_encode_error) { let range = extract_unicode_error_range(&err, vm)?; - let s = PyStrRef::try_from_object(vm, vm.get_attribute(err.clone(), "object")?)?; + let s = PyStrRef::try_from_object(vm, err.clone().get_attr("object", vm)?)?; let s_after_start = crate::common::str::try_get_chars(s.as_str(), range.start..).unwrap_or(""); let num_chars = range.len(); @@ -668,7 +668,7 @@ fn surrogateescape_errors(err: PyObjectRef, vm: &VirtualMachine) -> PyResult<(St Ok((out, range.end)) } else if is_decode_err(&err, vm) { let range = extract_unicode_error_range(&err, vm)?; - let s = PyStrRef::try_from_object(vm, vm.get_attribute(err.clone(), "object")?)?; + let s = PyStrRef::try_from_object(vm, err.clone().get_attr("object", vm)?)?; let s_after_start = crate::common::str::try_get_chars(s.as_str(), range.start..) .unwrap_or("") .as_bytes(); diff --git a/vm/src/exceptions.rs b/vm/src/exceptions.rs index 7852bfe2a7..4b87dcef66 100644 --- a/vm/src/exceptions.rs +++ b/vm/src/exceptions.rs @@ -49,7 +49,7 @@ impl VirtualMachine { let _ = self.write_exception(&mut py_io::IoWriter(io::stderr()), exc); } }; - if let Ok(excepthook) = vm.get_attribute(vm.sys_module.clone(), "excepthook") { + if let Ok(excepthook) = vm.sys_module.clone().get_attr("excepthook", vm) { let (exc_type, exc_val, exc_tb) = vm.split_exception(exc.clone()); if let Err(eh_exc) = vm.invoke(&excepthook, (exc_type, exc_val, exc_tb)) { write_fallback(&eh_exc, "Error in sys.excepthook:"); diff --git a/vm/src/format.rs b/vm/src/format.rs index c2cbd22878..8815a75cbe 100644 --- a/vm/src/format.rs +++ b/vm/src/format.rs @@ -812,7 +812,7 @@ impl FormatString { for name_part in parts { match name_part { FieldNamePart::Attribute(attribute) => { - argument = vm.get_attribute(argument, attribute.as_str())?; + argument = argument.get_attr(attribute.as_str(), vm)?; } FieldNamePart::Index(index) => { argument = argument.get_item(index, vm)?; diff --git a/vm/src/frame.rs b/vm/src/frame.rs index 3f7ce5de79..e9748618ca 100644 --- a/vm/src/frame.rs +++ b/vm/src/frame.rs @@ -827,7 +827,7 @@ impl ExecutingFrame<'_> { } bytecode::Instruction::SetupWith { end } => { let context_manager = self.pop_value(); - let exit = vm.get_attribute(context_manager.clone(), "__exit__")?; + let exit = context_manager.clone().get_attr("__exit__", vm)?; self.push_value(exit); // Call enter: let enter_res = vm.call_special_method(context_manager, "__enter__", ())?; @@ -837,7 +837,7 @@ impl ExecutingFrame<'_> { } bytecode::Instruction::BeforeAsyncWith => { let mgr = self.pop_value(); - let aexit = vm.get_attribute(mgr.clone(), "__aexit__")?; + let aexit = mgr.clone().get_attr("__aexit__", vm)?; self.push_value(aexit); let aenter_res = vm.call_special_method(mgr, "__aenter__", ())?; self.push_value(aenter_res); @@ -1041,14 +1041,16 @@ impl ExecutingFrame<'_> { let expr = self.pop_value(); let displayhook = vm - .get_attribute(vm.sys_module.clone(), "displayhook") + .sys_module + .clone() + .get_attr("displayhook", vm) .map_err(|_| vm.new_runtime_error("lost sys.displayhook".to_owned()))?; vm.invoke(&displayhook, (expr,))?; Ok(None) } bytecode::Instruction::LoadBuildClass => { - self.push_value(vm.get_attribute(vm.builtins.clone(), "__build_class__")?); + self.push_value(vm.builtins.clone().get_attr("__build_class__", vm)?); Ok(None) } bytecode::Instruction::UnpackSequence { size } => { @@ -1166,11 +1168,13 @@ impl ExecutingFrame<'_> { return Ok(obj); } // fallback to importing '{module.__name__}.{name}' from sys.modules - let mod_name = vm.get_attribute(module, "__name__").map_err(|_| err())?; + let mod_name = module.get_attr("__name__", vm).map_err(|_| err())?; let mod_name = mod_name.downcast::().map_err(|_| err())?; let full_mod_name = format!("{}.{}", mod_name, name); let sys_modules = vm - .get_attribute(vm.sys_module.clone(), "modules") + .sys_module + .clone() + .get_attr("modules", vm) .map_err(|_| err())?; sys_modules.get_item(full_mod_name, vm).map_err(|_| err()) } @@ -1499,7 +1503,7 @@ impl ExecutingFrame<'_> { // FIXME: turn return type to PyResult then ExecutionResult will be simplified None if vm.is_none(&val) => PyIter::new(gen).next(vm), None => { - let meth = vm.get_attribute(gen.clone(), "send")?; + let meth = gen.clone().get_attr("send", vm)?; PyIterReturn::from_pyresult(vm.invoke(&meth, (val,)), vm) } } @@ -1790,7 +1794,7 @@ impl ExecutingFrame<'_> { fn load_attr(&mut self, vm: &VirtualMachine, attr: bytecode::NameIdx) -> FrameResult { let attr_name = self.code.names[attr as usize].clone(); let parent = self.pop_value(); - let obj = vm.get_attribute(parent, attr_name)?; + let obj = parent.get_attr(attr_name, vm)?; self.push_value(obj); Ok(None) } diff --git a/vm/src/import.rs b/vm/src/import.rs index 497c2ab7fa..2205715cae 100644 --- a/vm/src/import.rs +++ b/vm/src/import.rs @@ -29,11 +29,11 @@ pub(crate) fn init_importlib( let importlib = enter_vm(vm, || { let importlib = import_frozen(vm, "_frozen_importlib")?; let impmod = import_builtin(vm, "_imp")?; - let install = vm.get_attribute(importlib.clone(), "_install")?; + let install = importlib.clone().get_attr("_install", vm)?; vm.invoke(&install, (vm.sys_module.clone(), impmod))?; Ok(importlib) })?; - vm.import_func = vm.get_attribute(importlib.clone(), "__import__")?; + vm.import_func = importlib.clone().get_attr("__import__", vm)?; if initialize_parameter == InitParameter::External && cfg!(feature = "rustpython-compiler") { enter_vm(vm, || { @@ -47,7 +47,7 @@ pub(crate) fn init_importlib( import_builtin(vm, "_io")?; import_builtin(vm, "marshal")?; - let install_external = vm.get_attribute(importlib, "_install_external_importers")?; + let install_external = importlib.get_attr("_install_external_importers", vm)?; vm.invoke(&install_external, ())?; // Set pyc magic number to commit hash. Should be changed when bytecode will be more stable. let importlib_external = vm.import("_frozen_importlib_external", None, 0)?; @@ -60,8 +60,8 @@ pub(crate) fn init_importlib( vm.set_attr(&importlib_external, "MAGIC_NUMBER", magic)?; let zipimport_res = (|| -> PyResult<()> { let zipimport = vm.import("zipimport", None, 0)?; - let zipimporter = vm.get_attribute(zipimport, "zipimporter")?; - let path_hooks = vm.get_attribute(vm.sys_module.clone(), "path_hooks")?; + let zipimporter = zipimport.get_attr("zipimporter", vm)?; + let path_hooks = vm.sys_module.clone().get_attr("path_hooks", vm)?; let path_hooks = list::PyListRef::try_from_object(vm, path_hooks)?; path_hooks.insert(0, zipimporter); Ok(()) @@ -100,7 +100,7 @@ pub fn import_builtin(vm: &VirtualMachine, module_name: &str) -> PyResult { }) .and_then(|make_module_func| { let module = make_module_func(vm); - let sys_modules = vm.get_attribute(vm.sys_module.clone(), "modules")?; + let sys_modules = vm.sys_module.clone().get_attr("modules", vm)?; sys_modules.set_item(module_name, module.clone(), vm)?; Ok(module) }) @@ -132,7 +132,7 @@ pub fn import_codeobj( let module = vm.new_module(module_name, attrs.clone(), None); // Store module in cache to prevent infinite loop with mutual importing libs: - let sys_modules = vm.get_attribute(vm.sys_module.clone(), "modules")?; + let sys_modules = vm.sys_module.clone().get_attr("modules", vm)?; sys_modules.set_item(module_name, module.clone(), vm)?; // Execute main code in module: diff --git a/vm/src/protocol/object.rs b/vm/src/protocol/object.rs index 711aa8fa3d..b572b20064 100644 --- a/vm/src/protocol/object.rs +++ b/vm/src/protocol/object.rs @@ -9,7 +9,7 @@ use crate::{ protocol::PyIter, pyref_type_error, types::{Constructor, PyComparisonOp}, - PyObjectRef, PyResult, TryFromObject, VirtualMachine, + PyObjectRef, PyResult, TryFromObject, TypeProtocol, VirtualMachine, }; // RustPython doesn't need these items @@ -23,8 +23,16 @@ impl PyObjectRef { self.get_attr(attr_name, vm).map(|o| vm.is_none(&o)) } + // get_attribute should be used for full attribute access (usually from user code). + #[cfg_attr(feature = "flame-it", flame("PyObjectRef"))] pub fn get_attr(self, attr_name: impl IntoPyStrRef, vm: &VirtualMachine) -> PyResult { - vm.get_attribute(self, attr_name) + let attr_name = attr_name.into_pystr_ref(vm); + vm_trace!("object.__getattribute__: {:?} {:?}", obj, attr_name); + let getattro = self + .class() + .mro_find_map(|cls| cls.slots.getattro.load()) + .unwrap(); + getattro(self, attr_name, vm) } // PyObject *PyObject_GenericGetAttr(PyObject *o, PyObject *name) diff --git a/vm/src/pyobjectrc.rs b/vm/src/pyobjectrc.rs index 25bec3e4b6..2a38e660c4 100644 --- a/vm/src/pyobjectrc.rs +++ b/vm/src/pyobjectrc.rs @@ -378,7 +378,7 @@ fn print_del_error(e: PyBaseExceptionRef, zelf: &PyObjectRef, vm: &VirtualMachin } let tb_module = vm.import("traceback", None, 0).unwrap(); // TODO: set exc traceback - let print_stack = vm.get_attribute(tb_module, "print_stack").unwrap(); + let print_stack = tb_module.get_attr("print_stack", vm).unwrap(); vm.invoke(&print_stack, ()).unwrap(); if let Ok(repr) = vm.to_repr(e.as_object()) { diff --git a/vm/src/scope.rs b/vm/src/scope.rs index 66fa8fd826..0ab2587d30 100644 --- a/vm/src/scope.rs +++ b/vm/src/scope.rs @@ -131,7 +131,7 @@ impl Scope { // if let Some(value) = self.globals.get_item_option(name.clone(), vm).unwrap() { // Some(value) // } else { - // vm.get_attribute(vm.builtins.clone(), name).ok() + // vm.builtins.clone().get_attr(name, vm).ok() // } // } diff --git a/vm/src/stdlib/ast.rs b/vm/src/stdlib/ast.rs index be3118727d..8a1acd0f5d 100644 --- a/vm/src/stdlib/ast.rs +++ b/vm/src/stdlib/ast.rs @@ -46,7 +46,8 @@ pub(crate) struct AstNode; impl AstNode { #[pymethod(magic)] fn init(zelf: PyObjectRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> { - let fields = vm.get_attribute(zelf.clone_class().into(), "_fields")?; + let obj: PyObjectRef = zelf.clone_class().into(); + let fields = obj.get_attr("_fields", vm)?; let fields = vm.extract_elements::(&fields)?; let numargs = args.args.len(); if numargs > fields.len() { diff --git a/vm/src/stdlib/builtins.rs b/vm/src/stdlib/builtins.rs index ddf7243287..7c0caf028e 100644 --- a/vm/src/stdlib/builtins.rs +++ b/vm/src/stdlib/builtins.rs @@ -321,7 +321,7 @@ mod builtins { if let OptionalArg::Present(default) = default { Ok(vm.get_attribute_opt(obj, attr)?.unwrap_or(default)) } else { - vm.get_attribute(obj, attr) + obj.get_attr(attr, vm) } } @@ -791,7 +791,7 @@ mod builtins { #[pyfunction] fn vars(obj: OptionalArg, vm: &VirtualMachine) -> PyResult { if let OptionalArg::Present(obj) = obj { - vm.get_attribute(obj, "__dict__").map_err(|_| { + obj.get_attr("__dict__", vm).map_err(|_| { vm.new_type_error("vars() argument must have __dict__ attribute".to_owned()) }) } else { diff --git a/vm/src/stdlib/codecs.rs b/vm/src/stdlib/codecs.rs index 69dafddec2..bf02c4783b 100644 --- a/vm/src/stdlib/codecs.rs +++ b/vm/src/stdlib/codecs.rs @@ -350,7 +350,7 @@ mod _codecs { ) -> PyResult { let f = cell.get_or_try_init(|| { let module = vm.import("_pycodecs", None, 0)?; - vm.get_attribute(module, name) + module.get_attr(name, vm) })?; vm.invoke(f, args) } diff --git a/vm/src/stdlib/imp.rs b/vm/src/stdlib/imp.rs index 4ba9fc9a59..d1676421b3 100644 --- a/vm/src/stdlib/imp.rs +++ b/vm/src/stdlib/imp.rs @@ -72,8 +72,8 @@ mod _imp { #[pyfunction] fn create_builtin(spec: PyObjectRef, vm: &VirtualMachine) -> PyResult { - let sys_modules = vm.get_attribute(vm.sys_module.clone(), "modules").unwrap(); - let name = vm.get_attribute(spec, "name")?; + let sys_modules = vm.sys_module.clone().get_attr("modules", vm).unwrap(); + let name = spec.get_attr("name", vm)?; let name = PyStrRef::try_from_object(vm, name)?; if let Ok(module) = sys_modules.get_item(name.clone(), vm) { diff --git a/vm/src/stdlib/io.rs b/vm/src/stdlib/io.rs index d15dfaffcd..d7a77c14d1 100644 --- a/vm/src/stdlib/io.rs +++ b/vm/src/stdlib/io.rs @@ -111,7 +111,7 @@ mod _io { } fn ensure_unclosed(file: &PyObjectRef, msg: &str, vm: &VirtualMachine) -> PyResult<()> { - if vm.get_attribute(file.clone(), "closed")?.try_to_bool(vm)? { + if file.clone().get_attr("closed", vm)?.try_to_bool(vm)? { Err(vm.new_value_error(msg.to_owned())) } else { Ok(()) @@ -287,7 +287,7 @@ mod _io { } fn file_closed(file: &PyObjectRef, vm: &VirtualMachine) -> PyResult { - vm.get_attribute(file.clone(), "closed")?.try_to_bool(vm) + file.clone().get_attr("closed", vm)?.try_to_bool(vm) } fn check_closed(file: &PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { if file_closed(file, vm)? { @@ -411,7 +411,7 @@ mod _io { #[pyproperty] fn closed(instance: PyObjectRef, vm: &VirtualMachine) -> PyResult { - vm.get_attribute(instance, "__closed") + instance.get_attr("__closed", vm) } #[pymethod] @@ -426,7 +426,7 @@ mod _io { vm: &VirtualMachine, ) -> PyResult> { let size = size.to_usize(); - let read = vm.get_attribute(instance, "read")?; + let read = instance.get_attr("read", vm)?; let mut res = Vec::new(); while size.map_or(true, |s| res.len() < s) { let read_res = ArgBytesLike::try_from_object(vm, vm.invoke(&read, (1,))?)?; @@ -825,7 +825,7 @@ mod _io { } } } - // vm.invoke(&vm.get_attribute(raw, "seek")?, args) + // vm.invoke(&raw.get_attr("seek", vm)?, args) if self.writable() { self.flush(vm)?; } @@ -1354,7 +1354,7 @@ mod _io { } pub fn repr_fileobj_name(obj: &PyObjectRef, vm: &VirtualMachine) -> PyResult> { - let name = match vm.get_attribute(obj.clone(), "name") { + let name = match obj.clone().get_attr("name", vm) { Ok(name) => Some(name), Err(e) if e.isinstance(&vm.ctx.exceptions.attribute_error) @@ -1498,15 +1498,18 @@ mod _io { } #[pyproperty] fn closed(&self, vm: &VirtualMachine) -> PyResult { - vm.get_attribute(self.lock(vm)?.check_init(vm)?.clone(), "closed") + self.lock(vm)? + .check_init(vm)? + .clone() + .get_attr("closed", vm) } #[pyproperty] fn name(&self, vm: &VirtualMachine) -> PyResult { - vm.get_attribute(self.lock(vm)?.check_init(vm)?.clone(), "name") + self.lock(vm)?.check_init(vm)?.clone().get_attr("name", vm) } #[pyproperty] fn mode(&self, vm: &VirtualMachine) -> PyResult { - vm.get_attribute(self.lock(vm)?.check_init(vm)?.clone(), "mode") + self.lock(vm)?.check_init(vm)?.clone().get_attr("mode", vm) } #[pymethod] fn fileno(&self, vm: &VirtualMachine) -> PyResult { @@ -2544,7 +2547,7 @@ mod _io { #[pyproperty] fn name(&self, vm: &VirtualMachine) -> PyResult { let buffer = self.lock(vm)?.buffer.clone(); - vm.get_attribute(buffer, "name") + buffer.get_attr("name", vm) } #[pyproperty] fn encoding(&self, vm: &VirtualMachine) -> PyResult { @@ -2870,7 +2873,7 @@ mod _io { #[pyproperty] fn closed(&self, vm: &VirtualMachine) -> PyResult { let buffer = self.lock(vm)?.buffer.clone(); - vm.get_attribute(buffer, "closed") + buffer.get_attr("closed", vm) } #[pyproperty] fn buffer(&self, vm: &VirtualMachine) -> PyResult { diff --git a/vm/src/stdlib/operator.rs b/vm/src/stdlib/operator.rs index 12408dffe1..8f2e562b1d 100644 --- a/vm/src/stdlib/operator.rs +++ b/vm/src/stdlib/operator.rs @@ -482,11 +482,11 @@ mod _operator { ) -> PyResult { let parts = attr.split('.').collect::>(); if parts.len() == 1 { - return vm.get_attribute(obj, parts[0]); + return obj.get_attr(parts[0], vm); } let mut obj = obj; for part in parts { - obj = vm.get_attribute(obj, part)?; + obj = obj.get_attr(part, vm)?; } Ok(obj) } @@ -638,7 +638,7 @@ mod _operator { } else { // If we have kwargs, create a partial function that contains them and pass back that // along with the args. - let partial = vm.get_attribute(vm.import("functools", None, 0)?, "partial")?; + let partial = vm.import("functools", None, 0)?.get_attr("partial", vm)?; let callable = vm.invoke( &partial, FuncArgs::new( diff --git a/vm/src/stdlib/os.rs b/vm/src/stdlib/os.rs index 82bd69873f..725165eeba 100644 --- a/vm/src/stdlib/os.rs +++ b/vm/src/stdlib/os.rs @@ -845,7 +845,7 @@ pub(super) mod _os { #[pymethod(magic)] fn repr(zelf: PyObjectRef, vm: &VirtualMachine) -> PyResult { - let name = match vm.get_attribute(zelf.clone(), "name") { + let name = match zelf.clone().get_attr("name", vm) { Ok(name) => Some(name), Err(e) if e.isinstance(&vm.ctx.exceptions.attribute_error) @@ -1733,7 +1733,7 @@ pub fn extend_module(vm: &VirtualMachine, module: &PyObjectRef) { let supports_dir_fd = PySet::default().into_ref(vm); let supports_follow_symlinks = PySet::default().into_ref(vm); for support in support_funcs { - let func_obj = vm.get_attribute(module.clone(), support.name).unwrap(); + let func_obj = module.clone().get_attr(support.name, vm).unwrap(); if support.fd.unwrap_or(false) { supports_fd.clone().add(func_obj.clone(), vm).unwrap(); } diff --git a/vm/src/stdlib/signal.rs b/vm/src/stdlib/signal.rs index 66c0770e73..4093c538fe 100644 --- a/vm/src/stdlib/signal.rs +++ b/vm/src/stdlib/signal.rs @@ -24,8 +24,9 @@ pub(crate) fn make_module(vm: &VirtualMachine) -> PyObjectRef { vm.signal_handlers.as_deref().unwrap().borrow_mut()[signum] = py_handler; } - let int_handler = vm - .get_attribute(module.clone(), "default_int_handler") + let int_handler = module + .clone() + .get_attr("default_int_handler", vm) .expect("_signal does not have this attr?"); _signal::signal(libc::SIGINT, int_handler, vm).expect("Failed to set sigint handler"); diff --git a/vm/src/stdlib/sre.rs b/vm/src/stdlib/sre.rs index a922537273..f528305e02 100644 --- a/vm/src/stdlib/sre.rs +++ b/vm/src/stdlib/sre.rs @@ -456,7 +456,7 @@ mod _sre { })?; if is_template { let re = vm.import("re", None, 0)?; - let func = vm.get_attribute(re, "_subx")?; + let func = re.get_attr("_subx", vm)?; let filter = vm.invoke(&func, (zelf.clone(), repl))?; (vm.is_callable(&filter), filter) } else { @@ -652,7 +652,7 @@ mod _sre { #[pymethod] fn expand(zelf: PyRef, template: PyStrRef, vm: &VirtualMachine) -> PyResult { let re = vm.import("re", None, 0)?; - let func = vm.get_attribute(re, "_expand")?; + let func = re.get_attr("_expand", vm)?; vm.invoke(&func, (zelf.pattern.clone(), zelf, template)) } diff --git a/vm/src/stdlib/sys.rs b/vm/src/stdlib/sys.rs index 2e3e8d5c83..92088622c8 100644 --- a/vm/src/stdlib/sys.rs +++ b/vm/src/stdlib/sys.rs @@ -725,15 +725,21 @@ impl PyStderr<'_> { } pub fn get_stdin(vm: &VirtualMachine) -> PyResult { - vm.get_attribute(vm.sys_module.clone(), "stdin") + vm.sys_module + .clone() + .get_attr("stdin", vm) .map_err(|_| vm.new_runtime_error("lost sys.stdin".to_owned())) } pub fn get_stdout(vm: &VirtualMachine) -> PyResult { - vm.get_attribute(vm.sys_module.clone(), "stdout") + vm.sys_module + .clone() + .get_attr("stdout", vm) .map_err(|_| vm.new_runtime_error("lost sys.stdout".to_owned())) } pub fn get_stderr(vm: &VirtualMachine) -> PyResult { - vm.get_attribute(vm.sys_module.clone(), "stderr") + vm.sys_module + .clone() + .get_attr("stderr", vm) .map_err(|_| vm.new_runtime_error("lost sys.stderr".to_owned())) } diff --git a/vm/src/stdlib/winapi.rs b/vm/src/stdlib/winapi.rs index 25b06fe265..33b86cf8a9 100644 --- a/vm/src/stdlib/winapi.rs +++ b/vm/src/stdlib/winapi.rs @@ -164,14 +164,14 @@ mod _winapi { ($attr:ident, $t:ty) => {{ si.StartupInfo.$attr = >::try_from_object( vm, - vm.get_attribute(args.startup_info.clone(), stringify!($attr))?, + args.startup_info.clone().get_attr(stringify!($attr), vm)?, )? .unwrap_or(0) as _ }}; ($attr:ident) => {{ si.StartupInfo.$attr = >::try_from_object( vm, - vm.get_attribute(args.startup_info.clone(), stringify!($attr))?, + args.startup_info.clone().get_attr(stringify!($attr), vm)?, )? .unwrap_or(0) }}; @@ -189,7 +189,7 @@ mod _winapi { let env = env.as_mut().map_or_else(null_mut, |v| v.as_mut_ptr()); let mut attrlist = getattributelist( - vm.get_attribute(args.startup_info.clone(), "lpAttributeList")?, + args.startup_info.clone().get_attr("lpAttributeList", vm)?, vm, )?; si.lpAttributeList = attrlist diff --git a/vm/src/vm.rs b/vm/src/vm.rs index a279070a39..9908df60bf 100644 --- a/vm/src/vm.rs +++ b/vm/src/vm.rs @@ -372,7 +372,7 @@ impl VirtualMachine { set_stdio("stdout", 1, "w")?; set_stdio("stderr", 2, "w")?; - let io_open = self.get_attribute(io, "open")?; + let io_open = io.get_attr("open", self)?; self.set_attr(&self.builtins, "open", io_open)?; } @@ -573,7 +573,8 @@ impl VirtualMachine { pub fn try_class(&self, module: &str, class: &str) -> PyResult { let class = self - .get_attribute(self.import(module, None, 0)?, class)? + .import(module, None, 0)? + .get_attr(class, self)? .downcast() .expect("not a class"); Ok(class) @@ -583,8 +584,9 @@ impl VirtualMachine { let module = self .import(module, None, 0) .unwrap_or_else(|_| panic!("unable to import {}", module)); - let class = self - .get_attribute(module.clone(), class) + let class = module + .clone() + .get_attr(class, self) .unwrap_or_else(|_| panic!("module {} has no class {}", module, class)); class.downcast().expect("not a class") } @@ -951,7 +953,7 @@ impl VirtualMachine { let cached_module = if weird { None } else { - let sys_modules = self.get_attribute(self.sys_module.clone(), "modules")?; + let sys_modules = self.sys_module.clone().get_attr("modules", self)?; sys_modules.get_item(module.clone(), self).ok() }; @@ -967,11 +969,13 @@ impl VirtualMachine { } } None => { - let import_func = self - .get_attribute(self.builtins.clone(), "__import__") - .map_err(|_| { - self.new_import_error("__import__ not found".to_owned(), module.clone()) - })?; + let import_func = + self.builtins + .clone() + .get_attr("__import__", self) + .map_err(|_| { + self.new_import_error("__import__ not found".to_owned(), module.clone()) + })?; let (locals, globals) = if let Some(frame) = self.current_frame() { (Some(frame.locals.clone()), Some(frame.globals.clone())) @@ -994,7 +998,7 @@ impl VirtualMachine { where F: Fn() -> String, { - self.get_attribute(cls.clone(), "__bases__").map_err(|e| { + cls.clone().get_attr("__bases__", self).map_err(|e| { // Only mask AttributeErrors. if e.class().is(&self.ctx.exceptions.attribute_error) { self.new_type_error(msg()) @@ -1009,7 +1013,7 @@ impl VirtualMachine { if obj.class().issubclass(typ.clone()) { Ok(true) } else if let Ok(icls) = - PyTypeRef::try_from_object(self, self.get_attribute(obj.clone(), "__class__")?) + PyTypeRef::try_from_object(self, obj.clone().get_attr("__class__", self)?) { if icls.is(&obj.class()) { Ok(false) @@ -1027,7 +1031,7 @@ impl VirtualMachine { ) }) .and_then(|_| { - let icls = self.get_attribute(obj.clone(), "__class__")?; + let icls = obj.clone().get_attr("__class__", self)?; if self.is_none(&icls) { Ok(false) } else { @@ -1075,7 +1079,7 @@ impl VirtualMachine { return Ok(true); } - let bases = self.get_attribute(derived, "__bases__")?; + let bases = derived.get_attr("__bases__", self)?; let tuple = PyTupleRef::try_from_object(self, bases)?; let n = tuple.len(); @@ -1389,21 +1393,6 @@ impl VirtualMachine { Ok(results) } - // get_attribute should be used for full attribute access (usually from user code). - #[cfg_attr(feature = "flame-it", flame("VirtualMachine"))] - pub fn get_attribute(&self, obj: PyObjectRef, attr_name: T) -> PyResult - where - T: IntoPyStrRef, - { - let attr_name = attr_name.into_pystr_ref(self); - vm_trace!("vm.__getattribute__: {:?} {:?}", obj, attr_name); - let getattro = obj - .class() - .mro_find_map(|cls| cls.slots.getattro.load()) - .unwrap(); - getattro(obj, attr_name, self) - } - pub fn get_attribute_opt( &self, obj: PyObjectRef, @@ -1412,7 +1401,7 @@ impl VirtualMachine { where T: IntoPyStrRef, { - match self.get_attribute(obj, attr_name) { + match obj.get_attr(attr_name, self) { Ok(attr) => Ok(Some(attr)), Err(e) if e.isinstance(&self.ctx.exceptions.attribute_error) => Ok(None), Err(e) => Err(e), diff --git a/wasm/lib/src/vm_class.rs b/wasm/lib/src/vm_class.rs index 258ce5a30a..31e979e739 100644 --- a/wasm/lib/src/vm_class.rs +++ b/wasm/lib/src/vm_class.rs @@ -282,9 +282,7 @@ impl WASMVirtualMachine { let module = vm.new_module(&name, attrs, None); - let sys_modules = vm - .get_attribute(vm.sys_module.clone(), "modules") - .into_js(vm)?; + let sys_modules = vm.sys_module.clone().get_attr("modules", vm).into_js(vm)?; sys_modules.set_item(name, module, vm).into_js(vm)?; Ok(()) @@ -303,9 +301,7 @@ impl WASMVirtualMachine { }); } - let sys_modules = vm - .get_attribute(vm.sys_module.clone(), "modules") - .into_js(vm)?; + let sys_modules = vm.sys_module.clone().get_attr("modules", vm).into_js(vm)?; sys_modules.set_item(name, py_module, vm).into_js(vm)?; Ok(())