"error: 'type' expects no type arguments, but 1 given" if type is aliased to another name

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

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

評価

難易度
3/5
見積もり時間
1〜2日
初心者へのやさしさ
48/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
停滞
技術スタック
python
領域
devtools

調査の方向性

まず、報告された Python 3.9 の再現コードを generictype.py で mypy とともに実行し、エイリアス固有のエラーを確認します。次に、mypy がジェネリックな組み込み型のエイリアスをどのように処理するかを追跡し、Type = type を対象とするリグレッションテストを追加して、既存の list と dict の動作を壊さずにチェックが成功することを確認します。

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

説明

affects-typeshed bug topic-pep-585 topic-type-alias

Bug Report

With the implementation of PEP 585 in Python 3.9, type now accepts a generic parameter. This makes typing.Type obsolete, reflected in its deprecation.

However, if the type built-in is assigned to another name and then used in a type declaration, mypy produces an error.

This does not occur with other types affected by PEP 585, or at least not all of them. I can confirm list and dict do not exhibit this behavior.

To Reproduce

Example code file:

generictype.py

Type = type

class MyInt(int):
    pass

x_type: Type[int] = MyInt
  1. Install mypy into a Python 3.9 environment.
  2. Execute mypy against the script: mypy .\generictype.py. No arguments or configuration are required.

Expected Behavior

This should result in a success run with no errors:

> mypy .\generictype.py
Success: no issues found in 1 source file

Actual Behavior

mypy identifies an error:

> mypy .\generictype.py
generictype.py:3: error: "type" expects no type arguments, but 1 given
Found 1 error in 1 file (checked 1 source file)

Also note that using x_type: type[int] = MyInt directly eliminates the error.

Your Environment

  • Mypy version used: mypy 0.800
  • Mypy command-line flags: None
  • Mypy configuration options from mypy.ini (and other config files): None
  • Python version used: Python 3.9.1 (inside a venv)
  • Operating system and version: Windows 10

Motivation

My actual code doesn't look exactly like the reproducing code above. I encountered it trying to make my code backwards compatible with Python 3.7+. My real usage looks more like this:

from __future__ import annotations

if sys.version_info >= (3, 9):
    List = list
    Type = type
else:
    # Legacy generic type annotation classes
    # Deprecated in Python 3.9
    # Remove once we no longer support Python 3.8 or lower
    from typing import List
    from typing import Type

class MyCustomContext:
    data: List[int]

    def __init__(self):
        self.data = []

    def __enter__(self) -> MyCustomContext:
        return self

    def add(i: int) -> None:
        self.data.append(i)

    def __exit__(
        self,
        ex_type: Optional[Type[Exception]],
        ex_value: Optional[Exception],
        ex_traceback: Optional[TracebackType],
    ) -> None:
        if ex_value is None and len(self.data) > 100:
            raise ValueError('Too much data')

For the time being, I can work around this by just continuing to use typing.Type, but I'd like to eliminate this deprecated class.

主要言語
Python
スター
20.6k
フォーク
3.3k
平均マージ
1日 18時間
マージ済み PR(30日)
54

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

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

はじめの一歩

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

python/mypy のほかの issue

python/mypy の issue をすべて見る

似ている issue

Python の issue をもっと見る

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

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