Typing Spec inconsistency for unpacking typed dict kwargs

Background: discussion w/ @erictraut on Add additional Unpack/kwargs conformance test cases by yangdanny97 · Pull Request #1918 · python/typing · GitHub

The typing spec has a section that disallows kwargs hinted with an unpacked TypedDict from being passed to another function that doesn’t have kwargs, since TypedDicts can have more keys than just the ones declared and spreading one can potentially cause a runtime error.

https://typing.readthedocs.io/en/latest/spec/callables.html#passing-kwargs-inside-a-function-to-another-function

Oddly, this restriction only applies to the pattern of “pass-through” kwargs, but not when spreading any other typed dict.

Here’s an example illustrate the issue:

class TD(TypedDict):
    v1: Required[int]
    v2: NotRequired[str]
    v3: Required[str]

def func(*, v1: int, v3: str, v2: str = "") -> None: ...

def test(x: TD, **kwargs: Unpack[TD]) -> None:
    func(**kwargs)  # not allowed
    func(**x)  # OK according to the spec, but equally unsafe

It’s also worth noting that none of the type checkers evaluated in the typing conformance tests currently implement this, even though it’s not an optional check in the spec.

In the interest of consistency, would it make sense to do one of the following?

  1. allow spreading typed dicts into functions without kwargs (unsafe)
  2. ban spreading any typed dicts into functions without kwargs (possible false-positives on existing code, since there’s no way to express closed TypedDicts yet)

If we go with #2, we could make an exception for PEP 728’s closed TypedDicts when/if it gets approved.