python/cpython · error · ValueError
The third value in the tuple must be an integer, or one of t
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.
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)
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 tuple size in creation of Decimal from list or tuple
- Invalid sign. The first value in the tuple should be an int
- The second value in the tuple must be composed of integers i
- argument must be a multiple of 32, with a maximum of {IEEE_C
- Cannot convert %r to Decimal
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/114dc6cb61ed4822.
Report an issue: GitHub.