Skip to content

Commit 075453f

Browse files
committed
Change warning message
1 parent 40b8a94 commit 075453f

File tree

4 files changed

+63
-48
lines changed

4 files changed

+63
-48
lines changed

src/errors/mod.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
use core::fmt;
2+
use std::borrow::Cow;
3+
14
use pyo3::prelude::*;
25

36
mod line_error;
@@ -30,3 +33,46 @@ pub fn py_err_string(py: Python, err: PyErr) -> String {
3033
Err(_) => "Unknown Error".to_string(),
3134
}
3235
}
36+
37+
// TODO: is_utf8_char_boundary, floor_char_boundary and ceil_char_boundary
38+
// with builtin methods once https://github.com/rust-lang/rust/issues/93743 is resolved
39+
// These are just copy pasted from the current implementation
40+
const fn is_utf8_char_boundary(value: u8) -> bool {
41+
// This is bit magic equivalent to: b < 128 || b >= 192
42+
(value as i8) >= -0x40
43+
}
44+
45+
pub fn floor_char_boundary(value: &str, index: usize) -> usize {
46+
if index >= value.len() {
47+
value.len()
48+
} else {
49+
let lower_bound = index.saturating_sub(3);
50+
let new_index = value.as_bytes()[lower_bound..=index]
51+
.iter()
52+
.rposition(|b| is_utf8_char_boundary(*b));
53+
54+
// SAFETY: we know that the character boundary will be within four bytes
55+
unsafe { lower_bound + new_index.unwrap_unchecked() }
56+
}
57+
}
58+
59+
pub fn ceil_char_boundary(value: &str, index: usize) -> usize {
60+
let upper_bound = Ord::min(index + 4, value.len());
61+
value.as_bytes()[index..upper_bound]
62+
.iter()
63+
.position(|b| is_utf8_char_boundary(*b))
64+
.map_or(upper_bound, |pos| pos + index)
65+
}
66+
67+
pub fn truncate_large_string<F: fmt::Write>(f: &mut F, val: Cow<'_, str>) -> std::fmt::Result {
68+
if val.len() > 50 {
69+
write!(
70+
f,
71+
"{}...{}",
72+
&val[0..floor_char_boundary(&val, 25)],
73+
&val[ceil_char_boundary(&val, val.len() - 24)..]
74+
)
75+
} else {
76+
write!(f, "{val}")
77+
}
78+
}

src/errors/validation_exception.rs

Lines changed: 2 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -386,51 +386,6 @@ impl ValidationError {
386386
}
387387
}
388388

389-
// TODO: is_utf8_char_boundary, floor_char_boundary and ceil_char_boundary
390-
// with builtin methods once https://github.com/rust-lang/rust/issues/93743 is resolved
391-
// These are just copy pasted from the current implementation
392-
const fn is_utf8_char_boundary(value: u8) -> bool {
393-
// This is bit magic equivalent to: b < 128 || b >= 192
394-
(value as i8) >= -0x40
395-
}
396-
397-
fn floor_char_boundary(value: &str, index: usize) -> usize {
398-
if index >= value.len() {
399-
value.len()
400-
} else {
401-
let lower_bound = index.saturating_sub(3);
402-
let new_index = value.as_bytes()[lower_bound..=index]
403-
.iter()
404-
.rposition(|b| is_utf8_char_boundary(*b));
405-
406-
// SAFETY: we know that the character boundary will be within four bytes
407-
unsafe { lower_bound + new_index.unwrap_unchecked() }
408-
}
409-
}
410-
411-
pub fn ceil_char_boundary(value: &str, index: usize) -> usize {
412-
let upper_bound = Ord::min(index + 4, value.len());
413-
value.as_bytes()[index..upper_bound]
414-
.iter()
415-
.position(|b| is_utf8_char_boundary(*b))
416-
.map_or(upper_bound, |pos| pos + index)
417-
}
418-
419-
macro_rules! truncate_input_value {
420-
($out:expr, $value:expr) => {
421-
if $value.len() > 50 {
422-
write!(
423-
$out,
424-
", input_value={}...{}",
425-
&$value[0..floor_char_boundary($value, 25)],
426-
&$value[ceil_char_boundary($value, $value.len() - 24)..]
427-
)?;
428-
} else {
429-
write!($out, ", input_value={}", $value)?;
430-
}
431-
};
432-
}
433-
434389
pub fn pretty_py_line_errors<'a>(
435390
py: Python,
436391
input_type: InputType,
@@ -570,7 +525,8 @@ impl PyLineError {
570525
if !hide_input {
571526
let input_value = self.input_value.bind(py);
572527
let input_str = safe_repr(input_value);
573-
truncate_input_value!(output, &input_str.to_cow());
528+
write!(output, ", input_value=")?;
529+
super::truncate_large_string(&mut output, input_str.to_cow())?;
574530

575531
if let Ok(type_) = input_value.get_type().qualname() {
576532
write!(output, ", input_type={type_}")?;

src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,11 @@ use pyo3::{prelude::*, sync::GILOnceCell};
1212
#[macro_use]
1313
mod py_gc;
1414

15+
pub mod errors;
16+
1517
mod argument_markers;
1618
mod build_tools;
1719
mod definitions;
18-
mod errors;
1920
mod input;
2021
mod lookup_key;
2122
mod recursion_guard;

src/serializers/extra.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use crate::recursion_guard::ContainsRecursionState;
1515
use crate::recursion_guard::RecursionError;
1616
use crate::recursion_guard::RecursionGuard;
1717
use crate::recursion_guard::RecursionState;
18+
use crate::tools::safe_repr;
1819
use crate::PydanticSerializationError;
1920

2021
/// this is ugly, would be much better if extra could be stored in `SerializationState`
@@ -424,8 +425,19 @@ impl CollectWarnings {
424425
.get_type()
425426
.qualname()
426427
.unwrap_or_else(|_| PyString::new_bound(value.py(), "<unknown python object>"));
428+
429+
let input_str = safe_repr(value);
430+
let mut value_str = String::with_capacity(100);
431+
value_str.push_str("with value `");
432+
match crate::errors::truncate_large_string(&mut value_str, input_str.to_cow()) {
433+
Err(_) => value_str.clear(),
434+
Ok(()) => {
435+
value_str.push_str("` ");
436+
}
437+
};
438+
427439
self.add_warning(format!(
428-
"Expected `{field_type}` but got `{type_name}` - serialized value may not be as expected"
440+
"Expected `{field_type}` but got `{type_name}` {value_str}- serialized value may not be as expected"
429441
));
430442
}
431443
}

0 commit comments

Comments
 (0)