8000 TypedDict rules are unsound · Issue #6 · CarliJoy/intersection_examples · GitHub
[go: up one dir, main page]

8000 Skip to content
TypedDict rules are unsound #6
@JelleZijlstra

Description

@JelleZijlstra

I am looking at the current rules in https://github.com/CarliJoy/intersection_examples/blob/main/specification.rst#typeddicts, which say that if two TypedDict members of an intersection share the same field with different types, then the intersection contains a field that is a union of those two types.

from typing import TypedDict
class A(TypedDict):
    a: int
class B(TypedDict):
    a: str
def takes_a(a: A) -> None:
    print(a["a"] + 1)
def takes_ab(ab: A & B) -> None:
    assert_type(ab["a"], int | str)
    takes_a(ab) # legal, A & B is compatible with A
b: B = {"a": "x"}
takes_ab(b) # legal, but throws an error at runtime

A similar hole:

def takes_ab2(ab: A & B) -> None:
    ab["a"] = 42 # legal, as ab["a"] is of type int | str
b2: B = {"a": "x"}
takes_ab2(b2)
print(b2["a"]) # now it's an int!

Possibly the type of ab["a"] should actually be int & str, not int | str.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0