型チェッカーのディレクティブ

assert_type()

関数 typing.assert_type(val, typ) を使用すると、ユーザーは 静的型チェッカーに valtyp の推論された型を持つことを確認するように依頼できます。

型チェッカーが assert_type() の呼び出しに遭遇した場合、 値が指定された型でない場合はエラーを発行する必要があります:

def greet(name: str) -> None:
    assert_type(name, str)  # OK、`name` の推論された型は `str` です
    assert_type(name, int)  # 型チェッカーエラー

2 番目の引数は有効な type expression である必要があります。

reveal_type()

関数 reveal_type(obj) は、型チェッカーに 式の推論された静的型を明らかにさせます。

静的型チェッカーがこの関数の呼び出しに遭遇した場合、 引数の型を持つ診断を発行する必要があります。 例:

x: int = 1
reveal_type(x)  # 明らかにされた型は "builtins.int" です

# type: ignore コメント

特別なコメント # type: ignore は、型チェッカーの エラーを無視するために使用されます。

# type: ignore コメントは、エラーが参照する行に配置する必要があります:

import http.client
errors = {
    'not_found': http.client.NOT_FOUND  # type: ignore
}

ファイルの先頭にある行に # type: ignore コメントを単独で配置すると、 ファイル内のすべてのエラーが無視されます。 空行や他のコメント(シェバン行やコーディングクッキーなど)は、 # type: ignore コメントの前に置くことができます。

場合によっては、リントツールや他のコメントが型コメントと同じ行に必要な場合があります。 その場合、型コメントは他のコメントやリントマーカーの前に置く必要があります:

# type: ignore # <comment or other marker>

cast()

場合によっては、型チェッカーが異なる種類のヒントを必要とすることがあります。 プログラマーは、型チェッカーが推論できる型よりも制約された型の式を知っている場合があります。 例:

from typing import cast

def find_first_str(a: list[object]) -> str:
    index = next(i for i, x in enumerate(a) if isinstance(x, str))
    # ここに到達するのは、a に少なくとも 1 つの文字列がある場合のみです
    return cast(str, a[index])

一部の型チェッカーは、a[index] の型が str であることを推論できず、 object または Any のみを推論する場合がありますが、 コードがそのポイントに到達する場合、それは文字列である必要があります。 cast(t, x) 呼び出しは、型チェッカーに x の型が t であることを確信していることを伝えます。 t は有効な type expression である必要があります。 実行時には、キャストは常に式を変更せずに返します - 型をチェックせず、値を変換または強制しません。

TYPE_CHECKING

場合によっては、型チェッカー(または他の静的解析ツール)によって見られる必要があるが、 実行されるべきではないコードがあります。 そのような状況のために、typing モジュールは定数 TYPE_CHECKING を定義しており、 型チェック中(または他の静的解析中)には True と見なされますが、実行時には False と見なされます。 例:

import typing

if typing.TYPE_CHECKING:
    import expensive_mod

def a_func(arg: 'expensive_mod.SomeClass') -> None:
    a_var: expensive_mod.SomeClass = arg
    ...

(型注釈は引用符で囲む必要があり、これにより expensive_mod 参照が インタープリタの実行時から隠されます。 変数注釈では引用符は必要ありません。)

このアプローチは、インポートサイクルを処理するためにも役立つ場合があります。

@no_type_check

@typing.no_type_check デコレーターは、関数およびクラスに対して型チェッカーによってサポートされる場合があります。

型チェッカーが関数に対して no_type_check デコレーターをサポートする場合、 def ステートメントおよびその本体に含まれるすべての型エラーを抑制する必要があります。 また、すべてのパラメータおよび戻り値の型注釈を無視し、関数を注釈なしとして扱う必要があります。

クラスに適用された場合の no_type_check デコレーターの動作は、 現時点では型指定によって定義されていません。

バージョンおよびプラットフォームのチェック

型チェッカーは、簡単なバージョンおよびプラットフォームのチェックを理解することが期待されています。 例:

import sys

if sys.version_info >= (3, 12):
    # Python 3.12+
else:
    # Python 3.11 以下

if sys.platform == 'win32':
    # Windows 固有の定義
else:
    # Posix 固有の定義

"".join(reversed(sys.platform)) == "xunil" のような難読化を型チェッカーが理解することは期待しないでください。

@deprecated

(元々 PEP 702 で指定されています。)

warnings.deprecated() デコレーターは、クラス、関数、またはメソッドに適用して非推奨とするために使用できます。 これには typing.TypedDict および typing.NamedTuple の定義が含まれます。 オーバーロードされた関数では、特定のオーバーロードが非推奨であることを示すためにデコレーターを個別のオーバーロードに適用できます。 デコレーターは、オーバーロードの実装関数に適用することもでき、関数全体が非推奨であることを示します。

デコレーターは次の引数を取ります:

  • 非推奨メッセージを表す必須の位置引数。

  • 実行時の動作を制御する 2 つのキーワード引数 category および stacklevel (以下の「実行時の動作」を参照)。

位置引数は str 型であり、デコレーターが装飾されたオブジェクトの使用時に型チェッカーによって表示されるメッセージを含みます。 ツールは表示のために非推奨メッセージをクリーンアップする場合があります。 例として inspect.cleandoc() または同等のロジックを使用します。 メッセージは文字列リテラルである必要があります。 非推奨メッセージの内容はユーザーに任されていますが、非推奨オブジェクトが削除されるバージョンや推奨される代替 API に関する情報を含めることができます。

型チェッカーは、非推奨とマークされたオブジェクトの使用に遭遇した場合に診断を生成する必要があります。 非推奨のオーバーロードについては、非推奨のオーバーロードに解決されるすべての呼び出しが含まれます。 非推奨のクラスおよび関数については、次のものが含まれます:

  • モジュール、クラス、またはインスタンス属性を介した参照(module.deprecated_objectmodule.SomeClass.deprecated_method, module.SomeClass().deprecated_method

  • 定義モジュール内での非推奨オブジェクトの使用 (module.py 内の x = deprecated_object()

  • import * が使用される場合、モジュールからの非推奨オブジェクトの使用 (from module import *; x = deprecated_object()

  • from インポート(from module import deprecated_object

  • 関数の呼び出しを間接的にトリガーする構文。 例として、 クラス C__add__ メソッドが非推奨とマークされている場合、 C() + C() のコードは診断をトリガーする必要があります。 同様に、 プロパティのセッターが非推奨とマークされている場合、プロパティの設定を試みると診断がトリガーされる必要があります。

メソッドが @override デコレーター でマークされており、 オーバーライドされる基底クラスのメソッドが非推奨である場合、型チェッカーは診断を生成する必要があります。

非推奨が関係する追加のシナリオもあります。 例として、オブジェクトが typing.Protocol を実装しているが、 プロトコル準拠に必要なメソッドの 1 つが非推奨である場合です。 このようなシナリオは複雑であり、実際には発生する可能性が低いため、 型チェッカーはそれらを検出することを義務付けられていません。