Add name and obj attributes to PyAttributeError

Signed-off-by: snowapril <sinjihng@gmail.com>
This commit is contained in:
snowapril
2021-10-10 23:50:56 +09:00
parent db0d9df53f
commit ff54d8ae53
4 changed files with 25 additions and 4 deletions

View File

@@ -702,7 +702,10 @@ impl ExceptionZoo {
extend_exception!(PyZeroDivisionError, ctx, &excs.zero_division_error);
extend_exception!(PyAssertionError, ctx, &excs.assertion_error);
extend_exception!(PyAttributeError, ctx, &excs.attribute_error);
extend_exception!(PyAttributeError, ctx, &excs.attribute_error, {
"name" => ctx.none(),
"obj" => ctx.none(),
});
extend_exception!(PyBufferError, ctx, &excs.buffer_error);
extend_exception!(PyEOFError, ctx, &excs.eof_error);

View File

@@ -32,7 +32,10 @@ impl PyObjectRef {
.class()
.mro_find_map(|cls| cls.slots.getattro.load())
.unwrap();
getattro(self, attr_name, vm)
getattro(self.clone(), attr_name.clone(), vm).map_err(|exc| {
vm.set_attribute_error_context(&exc, self, attr_name);
exc
})
}
pub fn call_set_attr(

View File

@@ -1103,11 +1103,13 @@ impl PyMethod {
drop(cls);
vm.invoke(&getter, (obj, name)).map(Self::Attribute)
} else {
Err(vm.new_attribute_error(format!(
let exc = vm.new_attribute_error(format!(
"'{}' object has no attribute '{}'",
cls.name(),
name
)))
));
vm.set_attribute_error_context(&exc, obj.clone(), name);
Err(exc)
}
}

View File

@@ -1413,6 +1413,19 @@ impl VirtualMachine {
}
}
pub fn set_attribute_error_context(
&self,
exc: &PyBaseExceptionRef,
obj: PyObjectRef,
name: PyStrRef,
) {
if exc.class().is(&self.ctx.exceptions.attribute_error) {
let exc = exc.as_object();
exc.set_attr("name", name, self).unwrap();
exc.set_attr("obj", obj, self).unwrap();
}
}
// get_method should be used for internal access to magic methods (by-passing
// the full getattribute look-up.
pub fn get_method_or_type_error<F>(