python/cpython · error · ValueError
The third value in the tuple must be an integer, or one of…
Error message
The third value in the tuple must be an integer, or one of the strings 'F', 'n', 'N'.
What it means
In Decimal's tuple/list constructor, the third element (exponent) must be an int for finite numbers, or one of the exact strings 'F' (infinity), 'n', 'N' (NaN). Anything else — 'f', 'Inf', None, a float — raises this ValueError. Note the case-sensitivity: only uppercase 'F' means infinity while both 'n' and 'N' mean NaN.
Solutions
- Use an int exponent for finite values: Decimal((0, (1, 4), -1))
- Use the exact markers: 'F' for infinity, 'n' or 'N' for NaN
- If the marker may be arbitrary case, normalize it first: exp = exp.upper() if isinstance(exp, str) else exp, mapping 'INF'->'F', 'NAN'->'n'
Example fix
// before
d = Decimal((0, (1,), marker)) # marker='f' or 'NaN' -> ValueError
// after
MARK = {'f': 'F', 'inf': 'F', 'n': 'n', 'nan': 'n'}
d = Decimal((0, (1,), MARK.get(marker.lower(), marker))) Defensive patterns
Strategy: validation
Validate before calling
SPECIAL_EXP = ('F', 'n', 'N')
def valid_exp(e):
return isinstance(e, int) or e in SPECIAL_EXP
# normalize common markers before constructing:
def norm_exp(e):
if isinstance(e, str):
return {'f': 'F', 'inf': 'F', 'n': 'n', 'nan': 'n'}.get(e.lower(), e)
return e Type guard
def is_valid_third(e) -> bool:
return isinstance(e, int) or e in ('F', 'n', 'N') Try / catch
try:
d = Decimal((sign, digits, exp))
except ValueError as e:
if 'third value' in str(e):
d = Decimal((sign, digits, norm_exp(exp))) Prevention
- Remember case rules: 'F' = infinity (uppercase only), 'n'/'N' = NaN
- Don't substitute None for missing exponents; use 0 for finite integers
- Normalize marker strings at the deserialization boundary
When it happens
Trigger: Decimal((0, (1,), 'f')) (lowercase f); Decimal((0, (1,), None)); Decimal((0, (1,), 2.0)) (float exponent not int); Decimal((0, (1,), 'inf')).
Common situations: Deserializing triples where special-value markers were lowercased by JSON or a normalizer; replacing the exponent with None for 'no exponent'; copying as_tuple() output of a NaN ((0, (0,), 'n') style) but mutating the marker string.
Related errors
- Invalid sign. The first value in the tuple should be an…
- Invalid tuple size in creation of Decimal from list or…
- The second value in the tuple must be composed of integers…
- argument must be a multiple of 32, with a maximum of
- Cannot convert NaN to integer
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/114dc6cb61ed4822.
Report an issue: GitHub.
Appendix: source
Thrown at Lib/_pydecimal.py:593
# skip leading zeros
if digits or digit != 0:
digits.append(digit)
else:
raise ValueError("The second value in the tuple must "
"be composed of integers in the range "
"0 through 9.")
if value[2] in ('n', 'N'):
# NaN: digits form the diagnostic
self._int = ''.join(map(str, digits))
self._exp = value[2]
self._is_special = True
elif isinstance(value[2], int):
# finite number: digits give the coefficient
self._int = ''.join(map(str, digits or [0]))
self._exp = value[2]
self._is_special = False
else:
raise ValueError("The third value in the tuple must "
"be an integer, or one of the "
"strings 'F', 'n', 'N'.")
return self
if isinstance(value, float):
if context is None:
context = getcontext()
context._raise_error(FloatOperation,
"strict semantics for mixing floats and Decimals are "
"enabled")
value = Decimal.from_float(value)
self._exp = value._exp
self._sign = value._sign
self._int = value._int
self._is_special = value._is_special
return self
raise TypeError("Cannot convert %r to Decimal" % value)View on GitHub (pinned to bc6749cc3b)