Added detailed TypeError messages to enums with derive(FromPyOjbect)
This commit is contained in:
parent
4a99bfaaba
commit
1a8fec2e88
|
@ -51,43 +51,39 @@ impl<'a> Enum<'a> {
|
||||||
/// Build derivation body for enums.
|
/// Build derivation body for enums.
|
||||||
fn build(&self) -> TokenStream {
|
fn build(&self) -> TokenStream {
|
||||||
let mut var_extracts = Vec::new();
|
let mut var_extracts = Vec::new();
|
||||||
let mut error_names = String::new();
|
let mut error_names: Vec<String> = Vec::new();
|
||||||
for (i, var) in self.variants.iter().enumerate() {
|
for var in &self.variants {
|
||||||
let struct_derive = var.build();
|
let struct_derive = var.build();
|
||||||
let ext = quote!(
|
let ext = quote!(
|
||||||
let maybe_ret = || -> pyo3::PyResult<Self> {
|
let maybe_ret = || -> pyo3::PyResult<Self> {
|
||||||
#struct_derive
|
#struct_derive
|
||||||
}();
|
}();
|
||||||
|
|
||||||
if maybe_ret.is_ok() {
|
if maybe_ret.is_ok() {
|
||||||
return maybe_ret
|
return maybe_ret
|
||||||
}
|
}
|
||||||
if let Err(inner) = maybe_ret {
|
if let Err(inner) = maybe_ret {
|
||||||
err_reasons.push(format!("{}", inner))
|
err_reasons.push_str(&format!("{}\n", inner))
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
var_extracts.push(ext);
|
var_extracts.push(ext);
|
||||||
error_names.push_str(&var.err_name);
|
error_names.push(var.err_name.clone());
|
||||||
if i < self.variants.len() - 1 {
|
|
||||||
error_names.push_str(", ");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
let error_names = if self.variants.len() > 1 {
|
let error_names = if self.variants.len() > 1 {
|
||||||
format!("Union[{}]", error_names)
|
format!("Union[{}]", error_names.join(","))
|
||||||
} else {
|
} else {
|
||||||
error_names
|
error_names[0].clone()
|
||||||
};
|
};
|
||||||
let ty_name: String = self.enum_ident.to_string();
|
let ty_name = self.enum_ident.to_string();
|
||||||
quote!(
|
quote!(
|
||||||
let mut err_reasons: Vec<String> = Vec::new();
|
let mut err_reasons = String::new();
|
||||||
#(#var_extracts)*
|
#(#var_extracts)*
|
||||||
let type_name = obj.get_type().name()?;
|
let type_name = obj.get_type().name()?;
|
||||||
let err_msg = format!("Failed to extract type {}\n\nCaused by:\nTypeError: '{}' object cannot be converted to '{}'",
|
let mut err_msg = format!("Failed to extract type {}\n\nCaused by:\n TypeError: '{}' object cannot be converted to '{}'\n\n",
|
||||||
#ty_name,
|
#ty_name,
|
||||||
type_name,
|
&type_name,
|
||||||
#error_names);
|
#error_names);
|
||||||
println!("{:?}", err_reasons);
|
err_msg.push_str(&err_reasons);
|
||||||
Err(pyo3::exceptions::PyTypeError::new_err(err_msg))
|
Err(pyo3::exceptions::PyTypeError::new_err(err_msg))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -265,12 +261,10 @@ impl<'a> Container<'a> {
|
||||||
FieldGetter::GetItem(Some(key)) => quote!(get_item(#key)),
|
FieldGetter::GetItem(Some(key)) => quote!(get_item(#key)),
|
||||||
FieldGetter::GetItem(None) => quote!(get_item(stringify!(#ident))),
|
FieldGetter::GetItem(None) => quote!(get_item(stringify!(#ident))),
|
||||||
};
|
};
|
||||||
let conversion_error_msg = attrs.conversion_error
|
let conversion_error_msg = attrs.conversion_error.as_ref().map_or(
|
||||||
.as_ref()
|
format!("failed to extract field {}.{}", quote!(#self_ty), ident),
|
||||||
.map_or(format!("failed to extract field {}.{}",
|
|msg| msg.value(),
|
||||||
quote!(#self_ty),
|
);
|
||||||
ident),
|
|
||||||
|msg| msg.value());
|
|
||||||
let get_field = quote!(obj.#getter?);
|
let get_field = quote!(obj.#getter?);
|
||||||
let extractor = match &attrs.from_py_with {
|
let extractor = match &attrs.from_py_with {
|
||||||
None => quote!(#get_field.extract().map_err(|inner| {
|
None => quote!(#get_field.extract().map_err(|inner| {
|
||||||
|
|
|
@ -296,7 +296,7 @@ fn test_err_rename() {
|
||||||
assert!(f.is_err());
|
assert!(f.is_err());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
f.unwrap_err().to_string(),
|
f.unwrap_err().to_string(),
|
||||||
"TypeError: Failed to extract type Bar\n\nCaused by:\nTypeError: 'dict' object cannot be converted to 'Union[str, uint, int]'"
|
"TypeError: Failed to extract type Bar\n\nCaused by:\n TypeError: \'dict\' object cannot be converted to \'Union[str,uint,int]\'\n\nTypeError: failed to extract inner field of Bar :: A\n\nCaused by:\n TypeError: \'dict\' object cannot be converted to \'PyString\'\n\nTypeError: failed to extract inner field of Bar :: B\n\nCaused by:\n TypeError: \'dict\' object cannot be interpreted as an integer\n\nTypeError: failed to extract inner field of Bar :: C\n\nCaused by:\n TypeError: \'dict\' object cannot be interpreted as an integer\n\n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue