python / python/mypy

Generic type inferred wrong; curious difference betweer `aiter(f(x))` and `c = f(x); aiter(c)`

オープン
#16,376 コメント 13 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

bug topic-type-context
主要言語
Python
スター
20.6k
フォーク
3.3k
PR マージ指標
PR 指標を取得中

説明

Bug Report

Consider this code (playground):

from typing import TypeVar, Generic, Callable, Coroutine, Any, AsyncIterator

_T = TypeVar("_T")

class StartedToken:
    pass

class ProducerContext(Generic[_T]):
    pass

async def coro_to_aiter(
    coroutine: Callable[[ProducerContext[_T]], Coroutine[Any, Any, None]]
) -> AsyncIterator[_T | StartedToken]:
    yield StartedToken()

async def coro(ctx: ProducerContext[int]) -> None:
    pass

# Split into two lines, no error:
c = coro_to_aiter(coro)  # no error
it = aiter(c)  # no error

# The same on one line -> mypy error:
it2 = aiter(coro_to_aiter(coro))  # error: Argument 1 to "coro_to_aiter" has incompatible type ...

Expected Behavior

I would expect mypy to not error on the it2 definition line. Moreover, regardless of whether mypy can handle these definitions, I would expect to see the same behavior (error or absence of error) in the "Split into two lines" case and the "on one line" case.

Actual Behavior

I get this error on the it2 line, and no errors on other lines:

main.py:24: error: Argument 1 to "coro_to_aiter" has incompatible type "Callable[[ProducerContext[int]], Coroutine[Any, Any, None]]"; expected "Callable[[ProducerContext[int | StartedToken]], Coroutine[Any, Any, None]]" [arg-type]

Your Environment

  • Mypy version used: 1.6.1 (playground), current master
  • Python version used: 3.11, 3.12

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

issue の main.py 再現コードから始め、記載されている Python と mypy のバージョンを使用して、分割した aiter(coro_to_aiter(coro)) のケースとネストしたケースを比較します。ジェネリック型推論が各呼び出しをどのように処理するかを追跡し、この不一致に対する集中的な回帰テストを追加または更新します。両方の形式が一貫した期待どおりの診断を受ければ完了です。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
python
領域
devtools
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
停滞
明瞭さ
おおむね明確
初心者へのやさしさ
42/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。