python / python/mypy

Inferred attribute type feeds back as call context, rejecting its own defining assignment

Abierto
#21,809 1 comentario 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

bug
Lenguaje dominante
Python
Estrellas
20.6k
Forks
3.3k
Métricas de merge de PR
Métricas de PR pendientes

Descripción

Bug Report

Assigning a generic call returning K | None to a previously undeclared
self. attribute spuriously fails [arg-type] on that same assignment. The
attribute's inferred type (str | None) apparently comes back as call context
on a later pass, solving K = str | None; the invariant Mapping key then
rejects dict[str, str].

The same expression passes with no context, an annotated local, an annotated
attribute, or a reassigned local (whose second assignment is likewise checked
against its own inferred str | None) — the optional-stripping special case
seems skipped on the inferred-attribute path alone. A sync version (no
async/await) also passes, pointing at the deferred re-check await
triggers.

To Reproduce

from collections.abc import Mapping


async def select_one[K](options: Mapping[K, str]) -> K | None: ...


class ViaInferredAttr:
    async def m(self) -> None:
        cases = {"a": "x"}
        self._done = await select_one(cases)  # error (spurious)


async def via_local() -> None:
    cases = {"a": "x"}
    done = await select_one(cases)  # ok
    done = await select_one(cases)  # ok (context = inferred str | None)
    done2: str | None = await select_one(cases)  # ok


class ViaAnnotatedAttr:
    _done: str | None

    async def m(self) -> None:
        cases = {"a": "x"}
        self._done = await select_one(cases)  # ok

Expected Behavior

All call sites typecheck, with K = str.

Actual Behavior

repro.py:10: error: Argument 1 to "select_one" has incompatible type "dict[str, str]"; expected "Mapping[str | None, str]"  [arg-type]

The str | None key shows the return's | None leaked into K.

Your Environment

  • mypy 1.20.2 (compiled), no flags
  • Python 3.13

Related: #5874 (over-eager outer context with unions), #19304 (assignment target
changes results). New here: the context is self-inferred — no annotation exists
anywhere — and explicit spellings of the same type behave differently.

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comienza con el reproductor del issue y sigue la reverificación asíncrona diferida para una asignación a un atributo de self no declarado. Compara esa ruta con los casos locales y de atributos anotados que pasan, centrándote en cómo el contexto de retorno inferido llega a la inferencia de argumentos genéricos. Se considera terminado cuando el reproductor pasa con K inferido como str y una prueba de regresión cubre el comportamiento.

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
Tranquilo
Claridad
Bastante claro
Aptitud para principiantes
48/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.