Description
Bug Description
Currently having a PyO3 function that takes an integer raises a OverflowError
when called from Python with a value out of bound.
According to Python documentation, the use of OverflowError
for handling int
seems like a odd choice:
Raised when the result of an arithmetic operation is too large to be represented. This cannot occur for integers (which would rather raise MemoryError than give up).
However, for historical reasons, OverflowError is sometimes raised for integers that are outside a required range. Because of the lack of standardization of floating-point exception handling in C, most floating-point operations are not checked.
On the other hand, it is clearly defined that ValueError
is the way to go when passing an invalid value with right type (the current issue is literally the given example 😄 ):
Passing arguments of the wrong type (e.g. passing a list when an int is expected) should result in a TypeError, but passing arguments with the wrong value (e.g. a number outside expected boundaries) should result in a ValueError.
In practice this is footgun since 1. PyO3 documentation doesn't mention this behavior and 2. ValueError
is the de-facto standard for this kind of behavior
This creates hidden bugs when implementing types in PyO3 that are then used in validation framework, typically Pydantic.
Currently avoiding this issue consists on either manually handling PyInt
conversion in the Rust code, or manually handling OverflowError
in the Python code. In both case this is error prone since forgetting to do it has no impact on the happy case...
Steps to Reproduce
use pyo3::prelude::*;
#[pyfunction]
fn foo(x: u64) {
x * 2
}
>>> import foomodule
>>> foomodule.foo(-1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OverflowError: can't convert negative int to unsigned
Backtrace
Your operating system and version
Pop!_OS 22.04 LTS
Your Python version (python --version
)
Python 3.12
Your Rust version (rustc --version
)
rustc 1.85.0 (4d91de4e4 2025-02-17)
Your PyO3 version
0.22.6 (but the code responsible for this is present in master)
How did you install python? Did you use a virtualenv?
poetry
Additional Info
No response