python/cpython · error · TypeError

Cannot convert %r to Decimal

Error message

Cannot convert %r to Decimal

What it means

Decimal(value) supports str, int, float (with FloatOperation signal semantics), list/tuple triples, another Decimal, and internal _WorkRep values. Any other type falls through to this TypeError: 'Cannot convert %r to Decimal'. It is the catch-all rejection at the end of Decimal.__new__.

Source

Thrown at Lib/_pydecimal.py:611

                    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)

    @classmethod
    def from_number(cls, number):
        """Converts a real number to a decimal number, exactly.

        >>> Decimal.from_number(314)              # int
        Decimal('314')
        >>> Decimal.from_number(0.1)              # float
        Decimal('0.1000000000000000055511151231257827021181583404541015625')
        >>> Decimal.from_number(Decimal('3.14'))  # another decimal instance
        Decimal('3.14')
        """
        if isinstance(number, (int, Decimal, float)):
            return cls(number)
        raise TypeError("Cannot convert %r to Decimal" % number)

    @classmethod
    def from_float(cls, f):

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Convert to a supported type first: Decimal(str(fraction)) or Decimal(fraction.numerator) / Decimal(fraction.denominator)
  2. Use Decimal.from_number(x) for int/float/Decimal, or str(x) for numeric strings
  3. Branch on type before constructing when input is heterogeneous

Example fix

// before
d = Decimal(value)  # value may be None/Fraction/complex -> TypeError

// after
if isinstance(value, (str, int, float, Decimal, list, tuple)):
    d = Decimal(value)
else:
    d = Decimal(str(value))  # or raise your own descriptive error
Defensive patterns

Strategy: type-guard

Validate before calling

SUPPORTED = (str, int, float, Decimal, list, tuple)

def can_construct_decimal(v) -> bool:
    return isinstance(v, SUPPORTED)

Type guard

from decimal import Decimal

def is_decimal_constructible(v) -> bool:
    return isinstance(v, (str, int, float, list, tuple, Decimal))

Try / catch

try:
    d = Decimal(value)
except TypeError:
    d = Decimal(str(value))  # last resort, or raise a domain-specific error

Prevention

When it happens

Trigger: Decimal(None); Decimal(complex(1, 2)); Decimal(Fraction(1, 3)); Decimal(b'1.5'); Decimal([1.5]) (list with wrong contents fails differently, but a non-numeric type hits this branch).

Common situations: Loading YAML/JSON values that parsed as None for null fields; passing a numpy scalar or Fraction where the code assumed int/str; wrapping untrusted input in Decimal without type dispatch.

Related errors


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