Can't match a TypedDict with a Protocol
Nadie ha tomado este issue todavía.
- Lenguaje dominante
- Python
- Estrellas
- 20.6k
- Forks
- 3.3k
- Métricas de merge de PR
- Métricas de PR pendientes
Descripción
Bug Report
I was trying to use a Protocol to fish out the value type from a TypedDict type corresponding to a key Literal passed to a function, so I could bind it to a TypeVar. That didn't work, but in trying to debug that I noticed that it's just straight up not possible to get a TypedDict to match a simple Protocol that we can see at type-checking time it does in fact match.
To Reproduce
See https://mypy-play.net/?mypy=latest&python=3.12&gist=928611fe3fcf77630451b8ca6b26dfca
from typing import Literal, TypedDict, Protocol, Optional
class Foo(TypedDict):
bar: int
concrete_var: Foo = Foo(bar=5)
# This typechecks (though it has to be optional for some reason even if the key
# is Required in the TypedDict):
int_var: Optional[int] = concrete_var.get("bar")
class Gettable(Protocol):
def get(self, key: Literal["bar"]) -> Optional[int]: ...
# But we don't use that to know that the protocol matches. This fails:
test_var: Gettable = concrete_var
Actual Behavior
main.py:16: error: Incompatible types in assignment (expression has type "Foo", variable has type "Gettable") [assignment]
main.py:16: note: Following member(s) of "Foo" have conflicts:
main.py:16: note: Expected:
main.py:16: note: def get(self, key: Literal['bar']) -> int | None
main.py:16: note: Got:
main.py:16: note: @overload
main.py:16: note: def get(self, str, /) -> object
main.py:16: note: @overload
main.py:16: note: def [_T] get(self, str, /, default: object) -> object
Found 1 error in 1 file (checked 1 source file)
MyPy appears to have forgotten everything it ever knew about the types of the things in the TypedDict when it tries to match the get() method to the protocol.
Your Environment
- Mypy version used: 1.9.0
- Python version used: 3.10 and 3.12
Guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Línea de trabajo
Empieza ejecutando la reproducción enlazada de mypy-play con las definiciones de TypedDict y Protocol proporcionadas. Rastrea cómo se comparan TypedDict get overloads con Protocol methods; se considera terminado cuando la asignación indicada se acepta correctamente y existe cobertura de regresión en el área de pruebas existente pertinente.
Escrito por el modelo de indexación a partir del texto del issue.
Evaluación
- Stack tecnológico
- python
- Área
- compilers
- Tipo de issue
- Error
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Estado de actividad
- Estancado
- Claridad
- Bastante claro
- Aptitud para principiantes
- 45/100