Python-to-rust conversion of integer raises an `OverflowError` instead of `ValueError` when value is out of bounds
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 16.2k
- Forks
- 1k
- Avg merge
- 2d 6h
- Merged PRs (30d)
- 66
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
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with src/conversions/std/num.rs, where the issue links to the integer conversion code, and reproduce the u64 case with -1 or another out-of-bounds value. The conversion should raise ValueError rather than OverflowError for an integer with the right type but an invalid range.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, rust
- Domain
- backend-api-design
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100