pydantic/monty · info
u32 fits usize on supported targets
Error message
u32 fits usize on supported targets
What it means
Internal `expect` in `hex_encode` (binascii.hexlify): converts the `bytes_per_sep` magnitude from `u32` to `usize` after `unsigned_abs()`. On all supported platforms `usize` is at least 32 bits, so the conversion cannot fail. Not reachable through `binascii.hexlify` with any separator or `bytes_per_sep` value.
Source
Thrown at crates/monty/src/modules/binascii.rs:427
HeapData::LongInt(long) => {
// `&` on a `BigInt` is two's-complement, so this is Python's
// own `value & 0xffffffff` for negatives as well.
Ok((&long.0 & BigInt::from(u32::MAX)).to_u32().expect("masked below 2**32"))
}
_ => Err(ExcType::type_error_not_integer(&value.py_type_name(vm))),
},
_ => Err(ExcType::type_error_not_integer(&value.py_type_name(vm))),
}
}
/// Encodes bytes as lowercase hex, inserting `sep` every `bytes_per_sep` bytes.
///
/// A positive `bytes_per_sep` groups from the right, so any short group leads;
/// a negative one groups from the left. Zero, or no separator, means none.
fn hex_encode(data: &[u8], sep: Option<u8>, bytes_per_sep: i32) -> Vec<u8> {
let group = match sep {
Some(_) if bytes_per_sep != 0 && !data.is_empty() => usize::try_from(bytes_per_sep.unsigned_abs())
.expect("u32 fits usize on supported targets")
.min(data.len()),
// Without a separator, or with an empty input, emit one flat run.
_ => data.len().max(1),
};
// Groups are measured from the right when positive, so the leading group
// absorbs the remainder.
let lead = if bytes_per_sep > 0 {
match data.len() % group {
0 => group,
remainder => remainder,
}
} else {
group
};
let mut out = Vec::with_capacity(data.len() * 2 + data.len() / group);
for (index, byte) in data.iter().enumerate() {
if let Some(sep) = sepView on GitHub (pinned to adc986b362)
Solutions
- No runtime action; the code already documents the platform assumption in the expect message.
Defensive patterns
Strategy: validation
Prevention
- Use `usize::try_from(x.unsigned_abs())` for i32→usize conversions; never `as usize` on negative or large values.
When it happens
Trigger: Unreachable; would only matter on a hypothetical target where `usize` < 32 bits, or if `unsigned_abs()` were replaced with an unchecked cast.
Common situations: Contributor-only, e.g. platform-porting audits.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- one character
- gather commit frame id is not a GatherFuture
- gather item is not a Coroutine, ExternalFuture, or GatherFut
- Cannot get identity of Dereferenced object
- invalid ascii byte
AI-assisted analysis of pydantic/monty@adc986b362 (2026-09-13).
Data as JSON: /api/errors/5d8015923d801891.
Report an issue: GitHub.