Skip to content

Account for TypedDicts in narrowing of isinstance(..., dict) #1130

@JelleZijlstra

Description

@JelleZijlstra

Summary

We just closed #456, but there's one special case that needs more attention: isinstance(x, dict). The tricky part is that TypedDicts are instances of dict at runtime, but are not (generally) assignable to any materialization of dict[Any, Any]. (See the proposed spec change in python/typing#2072 for the details.)

Current behavior is as follows (playground):

from typing import TypedDict

class X(TypedDict):
    a: int

def _(x: list | X):
    if isinstance(x, dict):
        reveal_type(x)  # X & Top[dict[Unknown, Unknown]]
    else:
        reveal_type(x)  # list[Unknown] | (X & ~Top[dict[Unknown, Unknown]])

Mypy and pyright both infer X in the positive branch and list[Any] in the negative branch, which is what we'd want.

I know TypedDict support is still missing a lot of functionality, so things will change, but I see a few options:

Version

No response

Metadata

Metadata

Assignees

Labels

narrowingrelated to flow-sensitive type narrowingtypeddict

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions