Merge pull request #3331 from DimitrisJim/relocate_getattribute

Relocate `vm.get_attribute` to `obj.get_attr`
This commit is contained in:
Jeong YunWon
2021-10-17 23:12:59 +09:00
committed by GitHub
36 changed files with 158 additions and 140 deletions

View File

@@ -551,7 +551,9 @@ fn setup_main_module(vm: &VirtualMachine) -> PyResult<Scope> {
})
.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<Option<PyObjectRef>> {
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<PyObjectRef> = vm.extract_elements(&path_hooks)?;
for path_hook in path_hooks {
@@ -660,7 +662,7 @@ fn get_importer(path: &str, vm: &VirtualMachine) -> PyResult<Option<PyObjectRef>
}
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(());
}

View File

@@ -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(),

View File

@@ -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()?;

View File

@@ -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)),

View File

@@ -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()) {

View File

@@ -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,

View File

@@ -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(),
});
}

View File

@@ -377,8 +377,10 @@ impl PyFunction {
#[pymethod(magic)]
fn repr(zelf: PyRef<Self>, 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::<PyStr>().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<PyObjectRef> {
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)
}
}

View File

@@ -81,7 +81,8 @@ pub fn get_jit_arg_types(func: &PyRef<PyFunction>, 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(),

View File

@@ -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)
}
}

View File

@@ -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")]

View File

@@ -79,7 +79,7 @@ impl PyModule {
#[pymethod(magic)]
fn repr(zelf: PyRef<Self>, 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,))
}

View File

@@ -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))
}
}

View File

@@ -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::<PyType>() {
if !cls.is(&ty) && cls.issubclass(&ty) {
return Ok(cls);

View File

@@ -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)
}
}

View File

@@ -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<Range<usize>> {
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();

View File

@@ -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:");

View File

@@ -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)?;

View File

@@ -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::<PyStr>().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<PyIterReturn> 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)
}

View File

@@ -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:

View File

@@ -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)

View File

@@ -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()) {

View File

@@ -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()
// }
// }

View File

@@ -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::<PyStrRef>(&fields)?;
let numargs = args.args.len();
if numargs > fields.len() {

View File

@@ -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 {

View File

@@ -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)
}

View File

@@ -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) {

View File

@@ -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<bool> {
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<Vec<u8>> {
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<Option<PyStrRef>> {
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<PyStrRef> {
@@ -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 {

View File

@@ -482,11 +482,11 @@ mod _operator {
) -> PyResult<PyObjectRef> {
let parts = attr.split('.').collect::<Vec<_>>();
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(

View File

@@ -845,7 +845,7 @@ pub(super) mod _os {
#[pymethod(magic)]
fn repr(zelf: PyObjectRef, vm: &VirtualMachine) -> PyResult<String> {
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();
}

View File

@@ -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");

View File

@@ -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<Match>, 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))
}

View File

@@ -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()))
}

View File

@@ -164,14 +164,14 @@ mod _winapi {
($attr:ident, $t:ty) => {{
si.StartupInfo.$attr = <Option<$t>>::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 = <Option<_>>::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

View File

@@ -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<PyTypeRef> {
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<T>(&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<T>(
&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),

View File

@@ -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(())