{"record":{"id":"73c6f56d146b0328","repo":"python/cpython","slug":"expected-a-list-of-types-an-ellipsis-paramspec","errorCode":null,"errorMessage":"Expected a list of types, an ellipsis, ParamSpec, or Concatenate. Got {t_args}","messagePattern":"Expected a list of types, an ellipsis, ParamSpec, or Concatenate\\. Got (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"Lib/_collections_abc.py","lineNumber":479,"sourceCode":"\n    This sets ``__args__`` to a tuple containing the flattened\n    ``argtypes`` followed by ``resulttype``.\n\n    Example: ``Callable[[int, str], float]`` sets ``__args__`` to\n    ``(int, str, float)``.\n    \"\"\"\n\n    __slots__ = ()\n\n    def __new__(cls, origin, args):\n        if not (isinstance(args, tuple) and len(args) == 2):\n            raise TypeError(\n                \"Callable must be used as Callable[[arg, ...], result].\")\n        t_args, t_result = args\n        if isinstance(t_args, (tuple, list)):\n            args = (*t_args, t_result)\n        elif not _is_param_expr(t_args):\n            raise TypeError(f\"Expected a list of types, an ellipsis, \"\n                            f\"ParamSpec, or Concatenate. Got {t_args}\")\n        return super().__new__(cls, origin, args)\n\n    def __repr__(self):\n        if len(self.__args__) == 2 and _is_param_expr(self.__args__[0]):\n            return super().__repr__()\n        from annotationlib import type_repr\n        return (f'collections.abc.Callable'\n                f'[[{\", \".join([type_repr(a) for a in self.__args__[:-1]])}], '\n                f'{type_repr(self.__args__[-1])}]')\n\n    def __reduce__(self):\n        args = self.__args__\n        if not (len(args) == 2 and _is_param_expr(args[0])):\n            args = list(args[:-1]), args[-1]\n        return _CallableGenericAlias, (Callable, args)\n\n    def __getitem__(self, item):","sourceCodeStart":461,"sourceCodeEnd":497,"githubUrl":"https://github.com/python/cpython/blob/bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6/Lib/_collections_abc.py#L461-L497","documentation":"TypeError raised by collections.abc.CallableType.__new__ (via typing.Callable) when the first slot of the subscription is not a list/tuple of types, an ellipsis, a ParamSpec, or a Concatenate object. Callable insists its parameter position be one of those forms; a bare type, string, or arbitrary object there is rejected with the offending value echoed.","triggerScenarios":"typing.Callable[int, str] (bare type instead of [int]); typing.Callable['int', str] (forward-ref string in the wrong slot); programmatically passing None or a class where a list was intended; Callable[..., None] is fine but Callable[Ellipsis, None] misused via * unpacking can slip through as an invalid shape.","commonSituations":"Misremembering the Callable syntax (very common typing mistake); macro/codegen emitting a single type for parameters; annotations assembled from JSON/strings where the parameter list loses its list wrapper; mixing typing.Callable with collections.abc.Callable usage in runtime validation.","solutions":["Wrap the parameter types in a list: Callable[[int], str] instead of Callable[int, str].","Use Callable[..., R] for 'any arguments'.","Use a ParamSpec (P = ParamSpec('P'); Callable[P, R]) for propagating signatures of decorators.","Validate annotation shapes with typing.get_args() in test suites for code that generates annotations."],"exampleFix":"# before\nCallback = typing.Callable[int, str]  # TypeError: Expected a list of types, an ellipsis, ...\n\n# after\nCallback = typing.Callable[[int], str]\nAnyArgs  = typing.Callable[..., str]","handlingStrategy":"validation","validationCode":"import typing\n\ndef first_slot_ok(t_args) -> bool:\n    from typing import ParamSpec\n    from typing_extensions import Concatenate\n    return (\n        isinstance(t_args, (tuple, list))\n        or t_args is Ellipsis\n        or isinstance(t_args, (ParamSpec, Concatenate))\n    )","typeGuard":"def is_param_expr(x) -> bool:\n    import typing\n    try:\n        from typing_extensions import Concatenate\n    except ImportError:\n        Concatenate = ()\n    P = typing.ParamSpec\n    return isinstance(x, (list, tuple, P, Concatenate)) or x is Ellipsis","tryCatchPattern":"try:\n    Alias = typing.Callable[spec]\nexcept TypeError as e:\n    if 'Expected a list of types' in str(e):\n        Alias = typing.Callable[[spec[0]], spec[1]]  # repair: wrap params in a list\n    else:\n        raise","preventionTips":["Remember the bracket-in-bracket shape: Callable[[int, str], bool].","Use mypy/pyright in CI to catch malformed Callable subscriptions statically.","When building specs from data, always emit a list for the parameter slot."],"tags":["typing","collections-abc","type-hints","developer-error"],"backgroundTag":null,"analyzedSha":"bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6","analyzedAt":"2026-08-14T22:01:13.976Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}