python/cpython · error · TypeError

'{key}' is an invalid keyword argument for this function

Error message

'{key}' is an invalid keyword argument for this function

What it means

decimal.localcontext(**kwargs) applies keyword overrides to the managed context, but only for keys present in _context_attributes (prec, rounding, Emin, Emax, capitals, clamp, flags, traps, etc.). Any other keyword raises TypeError naming the invalid key, matching the context constructor's behavior.

Source

Thrown at Lib/_pydecimal.py:422

    >>> with localcontext():
    ...     ctx = getcontext()
    ...     ctx.prec += 2
    ...     print(ctx.prec)
    ...
    30
    >>> with localcontext(ExtendedContext):
    ...     print(getcontext().prec)
    ...
    9
    >>> print(getcontext().prec)
    28
    """
    if ctx is None:
        ctx = getcontext()
    ctx_manager = _ContextManager(ctx)
    for key, value in kwargs.items():
        if key not in _context_attributes:
            raise TypeError(f"'{key}' is an invalid keyword argument for this function")
        setattr(ctx_manager.new_context, key, value)
    return ctx_manager


def IEEEContext(bits, /):
    """
    Return a context object initialized to the proper values for one of the
    IEEE interchange formats.  The argument must be a multiple of 32 and less
    than IEEE_CONTEXT_MAX_BITS.
    """
    if bits <= 0 or bits > IEEE_CONTEXT_MAX_BITS or bits % 32:
        raise ValueError("argument must be a multiple of 32, "
                         f"with a maximum of {IEEE_CONTEXT_MAX_BITS}")

    ctx = Context()
    ctx.prec = 9 * (bits//32) - 2
    ctx.Emax = 3 * (1 << (bits//16 + 3))
    ctx.Emin = 1 - ctx.Emax

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Use the canonical names: prec (not precision), rounding (not round), Emin/Emax, capitals, clamp, traps, flags
  2. Check decimal._context_attributes / help(Context) for the accepted set on your version
  3. If passing user config, whitelist and map keys to valid names before calling

Example fix

// before
with localcontext(precision=10):
    ...

# after
with localcontext(prec=10):
    ...
Defensive patterns

Strategy: validation

Validate before calling

from decimal import _context_attributes

ALLOWED = set(_context_attributes)  # prec, rounding, Emin, Emax, ...

def clean_ctx_kwargs(kwargs: dict) -> dict:
    alias = {'precision': 'prec', 'round': 'rounding'}
    out = {}
    for k, v in kwargs.items():
        k = alias.get(k, k)
        if k not in ALLOWED:
            raise ValueError(f'unknown context attribute: {k}')
        out[k] = v
    return out

Type guard

from decimal import _context_attributes

def is_valid_ctx_kwarg(key: str) -> bool:
    return key in _context_attributes

Prevention

When it happens

Trigger: localcontext(precision=28) (correct name is prec); localcontext(round='DOWN') (correct is rounding); typos like localcontext(precs=10); passing context constructor args that are not context attributes (e.g. context-specific Emax spelling mistakes).

Common situations: Migrating from the C decimal or other languages where 'precision' is the word; copy-pasting between Context(prec=...) and localcontext(precision=...); version drift when new attributes were expected but the Python build is older.

Related errors


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