PyO3/pyo3 · error
out of range integral type conversion attempted on `elements
Error message
out of range integral type conversion attempted on `elements.len()`
What it means
`PyList::new` computes the collection's `size_hint()` lower bound and converts it to C's `Py_ssize_t`; on platforms where `usize` cannot fit into `Py_ssize_t` (e.g. 32-bit targets with collections > ~2^31 elements) the `try_into()` fails and this expect panics. PyO3 performs the check itself because CPython's `PyList_New` overflow error message is poor.
Source
Thrown at src/types/list.rs:100
///
/// This function will panic if `element`'s [`Iterator::size_hint`] implementation is incorrect.
/// All standard library structures implement this trait correctly, if they do, so calling this
/// function with (for example) [`Vec`]`<T>` or `&[T]` will always succeed.
#[track_caller]
pub fn new<'py, T>(
py: Python<'py>,
elements: impl IntoIterator<Item = T>,
) -> PyResult<Bound<'py, PyList>>
where
T: IntoPyObject<'py>,
{
let mut elements = elements.into_iter().map(|e| e.into_bound_py_any(py));
let (min_len, _) = elements.size_hint();
// PyList_New checks for overflow but has a bad error message, so we check ourselves
let len: Py_ssize_t = min_len
.try_into()
.expect("out of range integral type conversion attempted on `elements.len()`");
let list = unsafe { ffi::PyList_New(len).assume_owned(py).cast_into_unchecked() };
let count = (&mut elements)
.take(len as usize)
.try_fold(0, |count, item| unsafe {
#[cfg(not(Py_LIMITED_API))]
ffi::PyList_SET_ITEM(list.as_ptr(), count, item?.into_ptr());
#[cfg(Py_LIMITED_API)]
ffi::PyList_SetItem(list.as_ptr(), count, item?.into_ptr());
Ok::<_, PyErr>(count + 1)
})?;
assert_eq!(len, count, "Attempted to create PyList but `elements` was smaller than reported by its `size_hint` implementation.");
elements.try_for_each(|item| list.append(item?))?;
Ok(list)View on GitHub (pinned to ac9b6899d3)
Solutions
- Reduce the collection size or chunk the input before constructing the list
- Fix the custom iterator's `size_hint` if it reports an incorrect length
- Use a fallback construction (e.g. `PyList::empty` + `append` in a loop) for unbounded inputs
Example fix
// before
let list = PyList::new(py, huge_iter)?;
// after
let list = PyList::empty(py);
for item in huge_iter.take(1_000_000) { list.append(item)?; } Defensive patterns
Strategy: validation
Validate before calling
fn list_len_safe<T>(items: impl ExactSizeIterator<Item = T>) -> bool {
items.len() <= isize::MAX as usize
} Try / catch
// catch_unwind around list construction if input size is untrusted let result = std::panic::catch_unwind(|| PyList::new(py, items.clone()));
Prevention
- On 32-bit targets, cap collection sizes well below isize::MAX
- Never implement ExactSizeIterator with a guessed/bogus size_hint
- Prefer chunked incremental list building for unbounded inputs
When it happens
Trigger: Calling `PyList::new(py, iterable)` where the iterable's `size_hint().0` exceeds `Py_ssize_t::MAX` — only feasible with a custom `ExactSizeIterator` lying about its length or an enormous collection on a 32-bit platform.
Common situations: 32-bit builds (wasm32/i686) processing very large generated collections, or a custom iterator whose `size_hint` returns a bogus huge lower bound.
Related errors
- out of range integral type conversion attempted on `elements
- failed to convert tuple to list
- Attaching a thread to the interpreter is prohibited while a
- Cannot attach to the Python interpreter while it is finalizi
- Attaching a thread to the interpreter is currently prohibite
AI-assisted analysis of PyO3/pyo3@ac9b6899d3 (2026-09-05).
Data as JSON: /api/errors/3931365976375deb.
Report an issue: GitHub.