python/cpython · error · ValueError

Invalid tuple size in creation of Decimal from list or tuple

Error message

Invalid tuple size in creation of Decimal from list or tuple.  The list or tuple should have exactly three elements.

What it means

Decimal(value) accepts a list or tuple argument, but only if it has exactly three elements in the shape returned by Decimal.as_tuple(): (sign, digits_tuple, exponent). This ValueError is raised when the sequence length differs from 3, i.e. the sequence cannot be interpreted as a decimal triple at all.

Source

Thrown at Lib/_pydecimal.py:556

        if isinstance(value, Decimal):
            self._exp  = value._exp
            self._sign = value._sign
            self._int  = value._int
            self._is_special  = value._is_special
            return self

        # From an internal working value
        if isinstance(value, _WorkRep):
            self._sign = value.sign
            self._int = str(value.int)
            self._exp = int(value.exp)
            self._is_special = False
            return self

        # tuple/list conversion (possibly from as_tuple())
        if isinstance(value, (list,tuple)):
            if len(value) != 3:
                raise ValueError('Invalid tuple size in creation of Decimal '
                                 'from list or tuple.  The list or tuple '
                                 'should have exactly three elements.')
            # process sign.  The isinstance test rejects floats
            if not (isinstance(value[0], int) and value[0] in (0,1)):
                raise ValueError("Invalid sign.  The first value in the tuple "
                                 "should be an integer; either 0 for a "
                                 "positive number or 1 for a negative number.")
            self._sign = value[0]
            if value[2] == 'F':
                # infinity: value[1] is ignored
                self._int = '0'
                self._exp = value[2]
                self._is_special = True
            else:
                # process and validate the digits in value[1]
                digits = []
                for digit in value[1]:
                    if isinstance(digit, int) and 0 <= digit <= 9:

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Supply the full triple: Decimal((sign, tuple_of_int_digits_0_9, exponent)) e.g. Decimal((0, (1, 4, 2), -2)) == Decimal('1.42')
  2. If you meant to construct from a numeric string, pass the string instead: Decimal('1.42')
  3. If the tuple came from as_tuple() and was transformed, re-check the transformation preserves all three fields

Example fix

// before
d = Decimal((1, (4, 5)))  # ValueError: needs 3 elements

// after
d = Decimal((1, (4, 5), 0))  # Decimal('-45')
Defensive patterns

Strategy: validation

Validate before calling

def is_decimal_triple(v):
    return (isinstance(v, (list, tuple))
            and len(v) == 3
            and isinstance(v[0], int) and v[0] in (0, 1)
            and all(isinstance(d, int) and 0 <= d <= 9 for d in v[1])
            and (isinstance(v[2], int) or v[2] in ('F', 'n', 'N')))

# d = Decimal(v) if is_decimal_triple(v) else ...

Type guard

from typing import Tuple, Iterable

def is_decimal_triple(v) -> bool:
    return isinstance(v, (list, tuple)) and len(v) == 3

Try / catch

try:
    d = Decimal(candidate)
except (ValueError, TypeError) as e:
    raise ValueError(f'malformed decimal triple {candidate!r}') from e

Prevention

When it happens

Trigger: Decimal((1, (4, 5))) (missing exponent); Decimal([0, (1,), 2, 'extra']); Decimal((sign, digits)) where exponent was dropped by an intermediate function; Decimal(()) empty tuple.

Common situations: Round-tripping as_tuple() output through code that strips or appends fields; building Decimals from rows of a database/CSV where a column is missing; passing a coordinate pair or other 2-tuple that was never a decimal triple.

Related errors


AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14). Data as JSON: /api/errors/d47c7b8cef6c6e0c. Report an issue: GitHub.