RustPython/RustPython · error · ValueError
cannot round a NaN
Error message
cannot round a NaN
What it means
The one-argument round(Decimal) rescales to an integer with ROUND_HALF_EVEN, which is undefined for specials: a NaN raises this ValueError (infinity raises OverflowError). Note round(sNaN, 0) instead routes through quantize and returns a NaN with the diagnostic attached.
Source
Thrown at Lib/_pydecimal.py:1840
>>> round(Decimal('123.456'), -2)
Decimal('1E+2')
>>> round(Decimal('-Infinity'), 37)
Decimal('NaN')
>>> round(Decimal('sNaN123'), 0)
Decimal('NaN123')
"""
if n is not None:
# two-argument form: use the equivalent quantize call
if not isinstance(n, int):
raise TypeError('Second argument to round should be integral')
exp = _dec_from_triple(0, '1', -n)
return self.quantize(exp)
# one-argument form
if self._is_special:
if self.is_nan():
raise ValueError("cannot round a NaN")
else:
raise OverflowError("cannot round an infinity")
return int(self._rescale(0, ROUND_HALF_EVEN))
def __floor__(self):
"""Return the floor of self, as an integer.
For a finite Decimal instance self, return the greatest
integer n such that n <= self. If self is infinite or a NaN
then a Python exception is raised.
"""
if self._is_special:
if self.is_nan():
raise ValueError("cannot round a NaN")
else:
raise OverflowError("cannot round an infinity")
return int(self._rescale(0, ROUND_FLOOR))View on GitHub (pinned to aaeab4f754)
Solutions
- Gate on finiteness: r = round(d) if d.is_finite() else None.
- Reject NaN tokens at parse time so rounding never sees them.
- Catch ValueError around round() for untrusted input.
Example fix
# before r = round(Decimal(value_str)) # ValueError when value_str == 'nan' # after d = Decimal(value_str) r = round(d) if d.is_finite() else None
Defensive patterns
Strategy: validation
Validate before calling
r = round(d) if d.is_finite() else None
Type guard
def roundable_decimal(d):
return d.is_finite() Try / catch
try:
r = round(d)
except ValueError:
r = None # NaN policy Prevention
- Filter NaN sentinels before rounding pipelines.
- Use is_finite() to cover both ValueError and OverflowError cases.
- Prefer round(d, 0) via quantize semantics only when you understand sNaN handling there.
When it happens
Trigger: round(Decimal('NaN')); round(Decimal('sNaN')); rounding values parsed from strings like 'nan' or produced by 0/0-style operations under non-trapping contexts.
Common situations: Rounding user-supplied numeric fields where NaN is a valid token; processing sensor/datafeed NaN sentinels through a rounding step.
Related errors
- cannot convert NaN to integer ratio
- Cannot convert NaN to integer
- Invalid sign. The first value in the tuple should be an int
- The second value in the tuple must be composed of integers i
- The third value in the tuple must be an integer, or one of t
AI-assisted analysis of RustPython/RustPython@aaeab4f754 (2026-08-17).
Data as JSON: /api/errors/ab16a2c3e5edb14c.
Report an issue: GitHub.