Fix type() error message and BaseException.__str__

This commit is contained in:
Jeong YunWon
2020-02-01 03:58:10 +09:00
parent 7cdaba75ab
commit c366c2074c
4 changed files with 33 additions and 10 deletions

View File

@@ -1168,8 +1168,6 @@ class ClassCreationTests(unittest.TestCase):
with self.assertRaises(TypeError):
X = types.new_class("X", (int(), C))
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_one_argument_type(self):
expected_message = 'type.__new__() takes exactly 3 arguments (1 given)'

View File

@@ -15,6 +15,8 @@ exc = KeyError('message')
assert str(exc) == "'message'"
assert round_trip_repr(exc)
assert LookupError.__str__(exc) == "message"
exc = KeyError('message', 'another message')
assert str(exc) == "('message', 'another message')"
assert round_trip_repr(exc)

View File

@@ -131,7 +131,7 @@ impl PyBaseException {
#[pymethod(name = "__str__")]
fn str(&self, vm: &VirtualMachine) -> PyStringRef {
let str_args = exception_args_as_string(vm, self.args(), false);
let str_args = exception_args_as_string(vm, self.args(), true);
match str_args.into_iter().exactly_one() {
Err(i) if i.len() == 0 => PyString::from("").into_ref(vm),
Ok(s) => s,
@@ -616,6 +616,18 @@ fn make_arg_getter(idx: usize) -> impl Fn(PyBaseExceptionRef, &VirtualMachine) -
}
}
fn key_error_str(exc: PyBaseExceptionRef, vm: &VirtualMachine) -> PyStringRef {
let args = exc.args();
if args.as_slice().len() == 1 {
exception_args_as_string(vm, args, false)
.into_iter()
.exactly_one()
.unwrap()
} else {
exc.str(vm)
}
}
pub fn init(ctx: &PyContext) {
let excs = &ctx.exceptions;
@@ -638,6 +650,10 @@ pub fn init(ctx: &PyContext) {
"value" => ctx.new_property(make_arg_getter(0)),
});
extend_class!(ctx, &excs.key_error, {
"__str__" => ctx.new_method(key_error_str),
});
extend_class!(ctx, &excs.unicode_decode_error, {
"encoding" => ctx.new_property(make_arg_getter(0)),
"object" => ctx.new_property(make_arg_getter(1)),

View File

@@ -254,13 +254,20 @@ impl PyClassRef {
fn tp_new(metatype: PyClassRef, args: PyFuncArgs, vm: &VirtualMachine) -> PyResult {
vm_trace!("type.__new__ {:?}", args);
if metatype.is(&vm.ctx.types.type_type) {
if args.args.len() == 1 && args.kwargs.is_empty() {
return Ok(args.args[0].class().into_object());
}
if args.args.len() != 3 {
return Err(vm.new_type_error("type() takes 1 or 3 arguments".to_string()));
}
let is_type_type = metatype.is(&vm.ctx.types.type_type);
if is_type_type && args.args.len() == 1 && args.kwargs.is_empty() {
return Ok(args.args[0].class().into_object());
}
if args.args.len() != 3 {
return Err(vm.new_type_error(if is_type_type {
"type() takes 1 or 3 arguments".to_string()
} else {
format!(
"type.__new__() takes exactly 3 arguments ({} given)",
args.args.len()
)
}));
}
let (name, bases, dict): (PyStringRef, PyIterable<PyClassRef>, PyDictRef) =