PyO3/pyo3 · warning
failed to create Python string
Error message
failed to create Python string
What it means
`CastError` formatting in pyo3 converts the human-readable description of a failed `isinstance`-style check (from/classinfo pair) into a Python string via `into_py_any`. The `.expect("failed to create Python string")` panics if that conversion to a Python `str` object fails. This is a nested failure: the primary failure is the type cast, and this panic only occurs if even building the error message fails.
Source
Thrown at src/err/cast_error.rs:79
}
}
struct CastErrorArguments {
from: Py<PyAny>,
classinfo: Py<PyAny>,
}
impl PyErrArguments for CastErrorArguments {
fn arguments(self, py: Python<'_>) -> Py<PyAny> {
format!(
"{}",
DisplayCastError {
from: &self.from.into_bound(py),
classinfo: &self.classinfo.into_bound(py),
}
)
.into_py_any(py)
.expect("failed to create Python string")
}
}
/// Convert `CastError` to Python `TypeError`.
impl core::convert::From<CastError<'_, '_>> for PyErr {
fn from(err: CastError<'_, '_>) -> PyErr {
let args = CastErrorArguments {
from: err.from.to_owned().unbind(),
classinfo: err.classinfo.unbind(),
};
exceptions::PyTypeError::new_err(args)
}
}
impl core::error::Error for CastError<'_, '_> {}
impl core::fmt::Display for CastError<'_, '_> {View on GitHub (pinned to ac9b6899d3)
Solutions
- Fix the underlying argument-type mismatch so the CastError is never constructed
- Avoid calling extension APIs after `Py_Finalize` / during interpreter shutdown
- Check memory availability if the process is near OOM
- Upgrade pyo3; error formatting paths have changed across versions
Example fix
// before obj.extract::<MyType>() # passing wrong Python type at shutdown // after # pass the correct type while the interpreter is fully alive func(MyType(...))
Defensive patterns
Strategy: validation
Validate before calling
# Validate argument types before calling the Rust extension
isinstance(value, expected_type) or raise TypeError(f'expected {expected_type}, got {type(value)}') Type guard
def is_expected_type(value, expected: type) -> bool:
return isinstance(value, expected) Prevention
- Type-check arguments before crossing into Rust
- Avoid extension calls during interpreter shutdown
- Keep memory headroom in constrained environments
- Keep pyo3 versions consistent across extensions
When it happens
Trigger: `DowncastError`/`CastError` Display formatting being converted with `.into_py_any(py)` when the Python interpreter cannot allocate a string, e.g. during interpreter finalization or out-of-memory.
Common situations: Calling Rust extension functions with wrong argument types during interpreter shutdown; extremely memory-constrained environments; panics surfacing as 'failed to create Python string' instead of a clean TypeError.
Related errors
- Neither abi3 or abi3t features are enabled
- Cannot target an abi3t version below {MINIMUM_SUPPORTED_VERS
- failed to run the Python interpreter at {}: {}
- Python script failed
- cannot set a minimum Python version {} higher than the inter
AI-assisted analysis of PyO3/pyo3@ac9b6899d3 (2026-09-05).
Data as JSON: /api/errors/3d10adaf0dcaca02.
Report an issue: GitHub.