Skip to content

Positional arguments to TypedDict constructor #2161

@JelleZijlstra

Description

@JelleZijlstra

The spec says "The constructor takes only keyword arguments, corresponding to the items of the TypedDict." This derives from wording in PEP 589 "It can be used as a callable object with keyword arguments corresponding to the TypedDict items. Non-keyword arguments are not allowed."

But at runtime, the TypedDict constructor also takes positional arguments. This works:

from typing import TypedDict
class TD1(TypedDict):
    a: int
class TD2(TD1):
    b: str

def f(x: TD2) -> TD1:
    return TD1(x)

Pyright allows this program; mypy does not and reports Expected keyword arguments, {...}, or dict(...) in TypedDict constructor.

The spec should say whether or not this should be allowed. (My opinion: it should be allowed, since it works at runtime and doesn't appear to break any type safety rule.)

At runtime, even more is allowed; the TypedDict constructor actually allows whatever dict() allows. So you could do TD1([("a", 1)]), or TD1(TD2, a=3). Pyright allows some but not all of that. I'm inclined to prohibit anything other than calls with keyword arguments and calls with a single positional argument of TypedDict type; anything else is rarely useful and prone to unsound behavior.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions