mypy icon indicating copy to clipboard operation
mypy copied to clipboard

A generic function taking a TypedDict type erroneously reports missing __required_keys__

Open gh-andre opened this issue 1 year ago • 0 comments

Bug Report

When calling a generic function taking a type variable bound to a typed dictionary type, MyPy reports that the typed dictionary type does not have __required_keys__ and __optional_keys__.

Pyright does not report any errors for the same code.

To Reproduce

from typing import Any, TypedDict, TypeVar, TypeGuard, Mapping

class _A(TypedDict):
    i: int
    
class _B(TypedDict):
    s: str
    
TD = TypeVar("TD", _A,_B)

def is_ab(td: type[TD], doc: Mapping[str, Any]) -> bool:
    for k in doc.keys():
        if k not in td.__required_keys__ and k not in td.__optional_keys__:
            return False
            
    for k in td.__required_keys__:
        if k not in doc:
            return False
            
    return True

def is_a(doc: Mapping[str, Any]) -> TypeGuard[_A]:
    return is_ab(_A, doc)

def is_b(doc: Mapping[str, Any]) -> TypeGuard[_B]:
    return is_ab(_B, doc)

xa: Mapping[str, Any] = {"i": 1}
xb: Mapping[str, Any] = {"s": "B"}

if is_a(xa):
  a: _A = xa

if is_b(xb):
  b: _B = xb

Expected Behavior

No errors should be reported because TD is bound to either _A or _B, which have all special TypedDict attributes.

Actual Behavior

When running MyPy against the code above, reports these errors:

mypy --strict td.py
td.py:13: error: "type[_A]" has no attribute "__required_keys__"  [attr-defined]
td.py:13: error: "type[_B]" has no attribute "__required_keys__"  [attr-defined]
td.py:13: error: "type[_A]" has no attribute "__optional_keys__"  [attr-defined]
td.py:13: error: "type[_B]" has no attribute "__optional_keys__"  [attr-defined]
td.py:16: error: "type[_A]" has no attribute "__required_keys__"  [attr-defined]
td.py:16: error: "type[_B]" has no attribute "__required_keys__"  [attr-defined]
Found 6 errors in 1 file (checked 1 source file)

Your Environment

  • Mypy version used: 1.10.0 on Windows
  • Mypy command-line flags: --strict (same behavior without)
  • Mypy configuration options from mypy.ini (and other config files): not used
  • Python version used: 3.10

gh-andre avatar Jun 11 '24 19:06 gh-andre