【Python × Pyright】型チェックって何? - Pyrightの現実的な設定で、厳しすぎない型チェックを実現する
この記事で解決できること
- 型チェックの基本を理解:初心者でも分かる用語解説
- 3つの設定パターン:basic/standard/strict それぞれの使い分け
- Pyrightで快適:VSCode統合、mypy の3-5倍高速
- Django/Wagtail対応:現実的な設定例とトラブル回避
- 開発速度を落とさない:実行時パフォーマンス影響なし
この記事は「Python開発環境シリーズ」の一部です
全体像を知りたい方は → Python開発、こんなことで困ってない?
あなたはこんなことで困っていませんか?
型チェックを導入したくても、厳しすぎたり、使い方が分からなかったりで諦めていませんか?
悩み1: そもそも型チェックって何?
- 「Pythonは動的型付けなのに、型チェック?」
- 「型ヒントって書かないといけないの?」
- 「JSのTypeScriptは聞いたことあるけど...」
- 「実行速度が遅くなるんじゃない?」
悩み2: 型チェッカー厳しすぎ問題
- 「mypy入れたらエラー1000件超え...」
- 「Django/Wagtail使ってるけど全部エラーになる」
- 「型スタブって何?どうすれば?」
- 「
reportMissingImportsとか設定が複雑すぎる」
悩み3: 開発速度が落ちる問題
- 「型ヒント書くのめんどくさい」
- 「エラー直すのに時間かかりすぎ」
- 「本当に効果あるの?」
- 「型チェック通すためだけに時間が取られる」
そもそも型チェックって何?
型チェックは、コードを実行する前に型エラーを検出する仕組みです。Pythonは動的型付け言語ですが、型ヒントを追加することで静的チェックが可能になります。
型チェック(Type Checking)とは
役割:コードの型エラーを実行前に検出
- 変数の型が間違っている
- 関数の引数の型が違う
- 戻り値の型が想定と異なる
重要:Pythonの型チェックは静的チェックであり、実行時には影響しません(速度低下なし)
型チェックなし(実行時エラー)
def add_numbers(a, b):
return a + b
result = add_numbers("5", 3)
# → "53" になる(意図しない結果)
# または
result = add_numbers(None, 3)
# → TypeError: unsupported operand type(s)実行してみないとエラーに気づけない
型チェックあり(実行前に検出)
def add_numbers(a: int, b: int) -> int:
return a + b
result = add_numbers("5", 3)
# ↑ Pyrightがエラーを表示
# Error: Argument of type "str" cannot
# be assigned to parameter "a"
# of type "int"実行前にエラーを発見できる
なぜ型チェックが必要?
バグの早期発見
実行前にエラーを検出。テストを書かなくても基本的な型エラーを発見できます。
ドキュメント機能
関数の入出力が明確になり、コメント不要で仕様が分かります。
リファクタリング支援
型変更時に影響範囲が自動で分かり、安全にリファクタリングできます。
IDE補完強化
より正確な補完候補が表示され、開発効率が上がります。
チーム開発での統一
型が明示されることで誤解が減り、コードレビューがスムーズになります。
実行時のパフォーマンスへの影響(重要)
型ヒントは実行時には完全に無視されるため、速度低下はありません(静的チェックのみ)。
# 型ヒントあり def add(a: int, b: int) -> int: return a + b # 上記は実行時には以下と完全に同じ def add(a, b): return a + b
出典: Python typing documentation - "The Python runtime does not enforce function and variable type annotations."
基本用語の解説
型チェックを理解するために、まず基本用語を押さえましょう。
型ヒント(Type Hints)
役割:Pythonコードに型情報を追加
- PEP 484(2014年)で導入
- 実行時には影響なし(静的チェックのみ)
- 標準ライブラリ
typingモジュール
from typing import List, Dict, Optional
# 変数の型ヒント
name: str = "Alice"
age: int = 30
scores: list[int] = [85, 90, 95] # Python 3.9+
# 関数の型ヒント
def greet(name: str) -> str:
return f"Hello, {name}!"
# Optional(値 or None)- Python 3.10+推奨記法
def find_user(user_id: int) -> str | None:
if user_id > 0:
return "Alice"
return None
# Dictの型ヒント
def get_user_data() -> dict[str, int]:
return {"age": 30, "score": 85}型スタブ(Type Stubs)
役割:外部ライブラリの型情報を提供
.pyiファイル(型情報のみ)- サードパーティライブラリ用
- django-stubs, types-requests, boto3-stubs等
なぜ必要?
# Djangoのコード(型ヒントなし) from django.db import models class User(models.Model): name = models.CharField(max_length=100) # ← nameの型は?Pyrightには分からない
django-stubsをインストールすると → Pyrightが「nameはstrだよ」と理解してくれる
2025年の状況
- Django公式には型ヒントなし →
django-stubs(コミュニティ製)が必要 - Wagtailも同様に型ヒントなし
django-types(2025年7月リリース): django-stubsのフォーク、非mypy型チェッカー対応強化
型チェッカー(Type Checker)
役割:型ヒントをチェックするツール
| ツール | 開発元 | リリース | 特徴 |
|---|---|---|---|
| mypy | Community | 2015年〜 | 最も有名(Python製) |
| Pyright | Microsoft | 2019年〜 | 高速(TypeScript製) |
| Pyre | Meta | - | 大規模向け |
| Pytype | - | 型推論強化 | |
| Pyrefly, ty | - | 2025年〜 | 新世代(Rust製、10-20倍高速) |
mypy vs Pyright:どちらを選ぶべき?
2大型チェッカーの特徴を比較し、自分に合ったツールを選びましょう。
| 項目 | mypy | Pyright |
|---|---|---|
| 開発元 | Python Community | Microsoft |
| 実装言語 | Python | TypeScript(Node.js) |
| 速度 | 普通 | 3-5倍速い |
| VSCode統合 | 手動設定必要 | Pylance拡張(標準) |
| リアルタイムチェック | 弱い | 強い(保存時即座) |
| Django対応 | プラグイン必要 | 設定で対応可 |
| 学習コスト | 高い(設定複雑) | 中(設定シンプル) |
| エコシステム | 成熟 | 成長中 |
| アーキテクチャ | 伝統的マルチパス | 遅延評価(JIT) |
Pyrightのメリット
- mypy の 3-5倍高速(大規模プロジェクトで顕著)
- VSCodeで標準(Pylance経由)
- リアルタイムチェック(保存時即座)
- 段階的な厳しさ設定(off/basic/standard/strict)
- pyproject.toml で一元管理
- インテリジェントな型推論
- ウォッチモード、並列処理対応
Pyrightのデメリット
- mypy より新しい(エコシステム未成熟)
- Node.js必要(VSCode以外で使う場合)
- 一部の高度な mypy 機能が未対応
- 日本語情報が mypy より少ない
どちらを選ぶべき?
- VSCode使ってる → Pyright推奨(統合が楽、高速)
- 既にmypy使用中 → mypy継続(無理に変えなくてOK)
- これから始める → Pyright推奨(速くて楽)
Pyright導入手順:10分で終わる
VSCode、pyproject.toml、VSCode設定の3ステップで完了します。
Step 1: VSCode拡張インストール(1分)
- VSCode を開く
- 拡張機能を検索:
Pylance - インストール
Pyrightが自動的に有効化されます
Pylance = Pyright + VSCode統合機能
Pylanceは、Pyrightエンジンに加えて、オートコンプリート、コードナビゲーション、インラインエラー表示などの機能を提供します。
Step 2: 基本設定(3分)
設定のポイント
pyproject.toml にPyrightの基本設定を追加します。Pythonバージョン、型チェックモード、仮想環境パス、対象ディレクトリを指定することで、プロジェクト全体の型チェックを有効化できます。
pythonVersion: 使用するPythonバージョンtypeCheckingMode: 型チェックの厳しさ(basic推奨)venvPath,venv: 仮想環境の場所include: チェック対象ディレクトリexclude: 除外するディレクトリ(migrations等)
3つの設定パターン
- basic: 基本的なエラーのみ、型ヒントがない関数も許容
- standard: より厳密なチェック、型ヒント推奨
- strict: 最も厳密、全ての関数に型ヒント必須
[tool.pyright] # Pythonバージョン pythonVersion = "3.11" # 型チェックの厳しさ(off/basic/standard/strict) typeCheckingMode = "basic" # 最初は basic がおすすめ # 仮想環境のパス venvPath = "." venv = ".venv" # チェック対象 include = ["myproject"] # 除外対象 exclude = [ "**/node_modules", "**/__pycache__", "**/migrations", # Djangoマイグレーション除外 ]
Step 3: VSCode設定(3分)
VSCode統合の設定
.vscode/settings.json に設定を追加することで、VSCode上でリアルタイムに型チェックが動作します。エラーの厳しさを調整し、開発体験を最適化できます。
typeCheckingMode: pyproject.tomlと同じ設定autoImportCompletions: 自動インポート補完diagnosticSeverityOverrides: エラーの厳しさ調整
これで保存時に自動型チェック!
{
"python.analysis.typeCheckingMode": "basic",
"python.analysis.autoImportCompletions": true,
"python.analysis.diagnosticSeverityOverrides": {
"reportGeneralTypeIssues": "warning", // エラーではなく警告
"reportOptionalMemberAccess": "none" // Optional系は無視
}
}悩み別の解決策
3つの悩みそれぞれに対する具体的な解決方法を紹介します。
悩み1解決: 型ヒントの書き方
基本の型ヒント
型ヒントの基本構文
Pythonの型ヒントは、関数の引数と戻り値に型情報を付与します。Python 3.9以降では、組み込み型(list, dict)を直接使えます。
int,str: 基本型list[int]: 型付きリスト(Python 3.9+)dict[str, str]: 型付き辞書str | None: Optional型(Python 3.10+)str | int: Union型(Python 3.10+)
# 基本型
def calculate_age(birth_year: int) -> int:
return 2025 - birth_year
# リスト(Python 3.9+)
def get_scores() -> list[int]:
return [85, 90, 95]
# 辞書
def get_user() -> dict[str, str]:
return {"name": "Alice", "email": "alice@example.com"}
# Optional(値 or None)- Python 3.10+推奨
def find_user(user_id: int) -> str | None:
if user_id > 0:
return "Alice"
return None
# Union型(Python 3.10+推奨記法)
def process_data(value: str | int) -> str:
return str(value)Python 3.10以降の新記法(PEP 604)
新記法の利点
Python 3.10以降では、|演算子を使った簡潔な型表記が可能になりました。typingモジュールのインポートが不要で、コードがシンプルになります。
Union[str, int]→str | intOptional[str]→str | None- typingモジュールのインポート不要
# 古い書き方(非推奨) from typing import Union, Optional def old_style(value: Union[str, int]) -> Optional[str]: return str(value) if value else None # 新しい書き方(推奨) def new_style(value: str | int) -> str | None: return str(value) if value else None
Django/Wagtailの型ヒント
フレームワーク固有の型
Django/Wagtailには専用の型が用意されています。django-stubsをインストールすることで、Pyrightがこれらの型を理解できます。
HttpRequest,HttpResponse: Djangoのリクエスト/レスポンスPage: Wagtailのページモデル
from django.http import HttpRequest, HttpResponse
from wagtail.models import Page
# Viewの型ヒント
def my_view(request: HttpRequest) -> HttpResponse:
return HttpResponse("Hello")
# Wagtail Page
def get_page_title(page: Page) -> str:
return page.title悩み2解決: Django/Wagtail対応設定(現実的な設定例)
問題:Django/Wagtailは型ヒントがない
# Djangoのコード from django.contrib.auth.models import User # Pyrightが型を理解できない... user = User.objects.get(id=1) print(user.username) # ← 型不明
→ エラーが大量に出てしまう
解決策1: 型スタブをインストール
型スタブの役割
django-stubsは、Djangoのための型情報を提供するパッケージです。これをインストールすることで、Pyrightが Django のクラスやメソッドの型を理解できるようになります。
django-stubs: Djangoの型情報types-*: サードパーティライブラリの型情報
# django-stubsをインストール uv add --dev django-stubs types-requests # これでPyrightがDjangoの型を理解してくれる
解決策2: 現実的な pyproject.toml 設定
Django/Wagtail向けの設定
Wagtailプロジェクトから引用した現実的な設定例です。reportMissingImports = false などの緩和設定により、Django/Wagtailでも快適に型チェックを利用できます。
typeCheckingMode = "basic": 現実的な厳しさreportMissingImports = false: importエラー無視reportOptionalCall = false: Optional系エラー緩和- migrations等を除外
ポイント
typeCheckingMode = "basic"が現実的reportMissingImports = falseでDjango/Wagtailのimportエラー回避reportOptionalCall = falseで Optional 系のエラー減らす
[tool.pyright] pythonVersion = "3.11" typeCheckingMode = "basic" # basicが現実的 venvPath = "." venv = ".venv" include = ["wagtail_template"] exclude = [ "**/node_modules", "**/__pycache__", "**/migrations", "**/venv", ] # Django/Wagtailでの現実的な設定(重要!) reportArgumentType = false # 引数型チェック緩和 reportAssignmentType = false # 代入型チェック緩和 reportOptionalCall = false # Optional系チェック無効 reportMissingImports = false # importエラー無視 # 上記設定で、Django/Wagtailでも快適に使える
依存関係の設定
必要な型スタブパッケージ
pyproject.tomlの[dependency-groups]セクションに、開発時に必要な型スタブパッケージを列挙します。主要なライブラリの型情報を網羅することで、より正確な型チェックが可能になります。
- Django関連: django-stubs
- AWS: boto3-stubs
- データ処理: pandas-stubs
- その他: types-* パッケージ
[dependency-groups] dev = [ "pyright>=1.1.402", "django-stubs>=5.2.0", "types-requests>=2.32.0.20250602", "boto3-stubs>=1.38.30", "celery-types>=0.23.0", "pandas-stubs>=2.2.3.250527", "types-redis>=4.6.0.20241004", "types-psycopg2>=2.9.21.20250516", "types-pillow>=10.2.0.20240822", ]
悩み3解決: 開発速度を落とさない工夫
3つの設定パターンから選ぶ
プロジェクトに合わせた設定
typeCheckingModeは、プロジェクトの規模や型安全性の要求に応じて選択できます。いつでも変更可能なので、まずは緩めのbasicから始めるのが現実的です。
- basic: 基本的なエラーのみ、型ヒントがない関数も許容
- standard: より厳密なチェック、型ヒント推奨
- strict: 最も厳密、全ての関数に型ヒント必須
ポイント:型チェックは「助け」であって「足かせ」ではありません。プロジェクトに合った設定を選びましょう。
# パターン1: 緩め(型チェックに慣れたい) [tool.pyright] typeCheckingMode = "basic" # パターン2: 標準(バランス重視) [tool.pyright] typeCheckingMode = "standard" # パターン3: 厳格(型安全性重視) [tool.pyright] typeCheckingMode = "strict"
特定ファイル・行を除外
柔軟な除外設定
型チェックを一時的に無効化したい場合、コメントで除外指定ができます。レガシーコードや複雑なロジックに対して有効です。
# pyright: ignore: ファイル全体を除外# pyright: ignore(行末): 特定行のみ除外# type: ignore[...]: 特定のエラーのみ無視
# ファイル全体を除外 # pyright: ignore # 特定行のみ除外 result = some_complex_function() # pyright: ignore # 特定のエラーのみ無視 # type: ignore[reportGeneralTypeIssues]
CI/CDでの型チェック
自動化の重要性
CI/CDパイプラインに型チェックを組み込むことで、マージ前に型エラーを検出できます。コードレビューの負担を軽減し、品質を保証します。
- プルリクエスト時に自動実行
- 型エラーがあればマージをブロック
- uvと組み合わせて高速実行
# .github/workflows/ci.yml - name: Type check run: uv run pyright
型チェックフロー図
Pyright導入後の開発フローを可視化します。
開発フロー(Pyright導入後)
1. コード編集 ↓ 2. 型ヒント追加 def greet(name: str) -> str: ↓ 3. ファイル保存 ↓(Pylanceが自動実行) 4. Pyrightが型チェック(即座、0.5秒以内) ↓(型エラーがあれば) 5. VSCode上に赤い波線表示 ↓ 6. エラーにマウスオーバー ↓ 7. エラー内容確認 "Argument of type 'int' cannot be assigned to parameter 'name' of type 'str'" ↓ 8. 修正 ↓ 9. 保存 → 再チェック → OK! → 実行前にバグ発見!
よくあるトラブルシューティング
Pyright導入時によくある問題と解決策をまとめました。
Pylanceが動かない
// .vscode/settings.json
{
"python.languageServer": "Pylance",
"python.analysis.typeCheckingMode": "basic"
}VSCode設定で明示的にPylanceを指定します。
型スタブが見つからない
# 型スタブをインストール uv add --dev django-stubs types-requests # または手動でpyproject.tomlに追加 [dependency-groups] dev = [ "django-stubs>=5.2.0", "types-requests>=2.32.0", ]
型スタブパッケージをインストールして型情報を提供します。
エラーが多すぎる場合
[tool.pyright] # 緩めの設定を選ぶ typeCheckingMode = "basic" # または一時的に無効化 # typeCheckingMode = "off"
設定パターンを見直して、プロジェクトに合ったものを選びます。
useLibraryCodeForTypes問題
# Wagtail/Django非型付けライブラリでの推論を無効化 [tool.pyright] useLibraryCodeForTypes = false
Pythonの型システムの歴史
Pythonの型システムは、2014年のPEP 484承認から急速に発展してきました。
型システムの進化
- 2006年: MyPy開発開始(Jukka Lehtosalo氏)
- 2014年: PEP 484承認(型ヒント標準化)
- 2015年: Python 3.5で型ヒント導入、mypy 0.1リリース
- 2016年: typing モジュール追加
- 2019年: Pyright発表(Microsoft)
- 2020年: Pylance発表(VSCode拡張)、PEP 585(
list[int]記法) - 2021年: Python 3.10でUnion型の
|記法導入(PEP 604) - 2022年: Python 3.11でSelf, TypeVarTuple追加
- 2023年: Pyright急成長(VSCodeデフォルト)
- 2024年: Python 3.12でtype文導入
- 2025年: Python 3.13で型システム強化、Rustベース型チェッカー(Pyrefly, ty)登場
なぜPyrightが選ばれる?
- VSCode標準(Pylance)
- mypy の 3-5倍高速
- リアルタイムチェック
- 設定がシンプル
パフォーマンス比較
Pyrightは、mypyと比較して3-5倍高速に動作します。大規模プロジェクトほど差が顕著です。
型チェック実行時間の比較(Djangoプロジェクト 5万行)
Pyrightアーキテクチャの優位性
遅延評価(Lazy Evaluation)
必要な部分だけ型評価し、無駄な処理を省きます。
インクリメンタル更新
変更箇所のみ再評価し、全体の再チェックを避けます。
並列処理
マルチコアCPUを活用して高速化します。
メモリ効率
大規模コードベースでもメモリ消費を抑えます。
重要:型ヒント自体は実行時のパフォーマンスに影響しません(静的チェックのみ)。
CI/CDでの使用例
GitHub Actionsでの型チェック自動化の例を紹介します。
GitHub Actions設定例
CI/CDパイプラインへの統合
GitHub Actionsを使って、プルリクエストやpush時に自動的に型チェックを実行します。uvを使うことで、依存関係のインストールと型チェックが高速に完了します。
- push/pull_request時に自動実行
- uvで依存関係を高速インストール
- pyrightで型チェックを実行
- エラーがあればCI失敗
ポイント
- CI/CDで型チェック必須化
- 開発時はVSCodeで快適に
- マージ前に必ずチェック
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
type-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install uv
run: curl -LsSf https://astral.sh/uv/install.sh | sh
- name: Setup Python & install dependencies
run: |
uv sync
- name: Run Pyright
run: |
uv run pyright型ヒントのベストプラクティス
効果的な型ヒントの書き方を学びましょう。
悪い例:曖昧な型
def process(data: list) -> list: # 曖昧 return data
何のリストか分からない
良い例:明確な型
def process(data: list[str]) -> list[int]: # 明確 return [len(s) for s in data]
入力も出力も明確
Optionalの使い方(Python 3.10+推奨記法)
新記法の利点
Python 3.10以降では、str | Noneの記法が推奨されます。typing.Optionalよりも直感的で、コードが簡潔になります。
str | None: 推奨される記法Optional[str]: 旧記法(非推奨)- typingモジュールのインポート不要
# Python 3.10以降は | None 推奨
def find_user(user_id: int) -> str | None:
if user_id > 0:
return "Alice"
return None
# 古い書き方(非推奨)
from typing import Optional
def find_user(user_id: int) -> Optional[str]:
...型エイリアス
複雑な型の簡略化
型エイリアスを使うことで、複雑な型定義を再利用可能な名前で表現できます。コードの可読性が向上し、型の変更も一箇所で済みます。
- 複雑な型に分かりやすい名前を付ける
- 型の変更が一箇所で済む
- コードの可読性が向上
# 複雑な型は別名をつける
UserDict = dict[str, str | int]
def get_user() -> UserDict:
return {"name": "Alice", "age": 30}公開APIに型ヒントを付ける
選択的な型ヒント
すべての関数に型ヒントを付ける必要はありません。公開API(外部から呼ばれる関数)に型ヒントを付けることで、インターフェースが明確になります。内部関数は省略可能です。
- 公開APIには必ず型ヒントを付ける
- 内部関数(
_で始まる)は省略可能 - インターフェースの明確化が目的
# 公開APIには型ヒント
def public_api(data: str) -> dict[str, str]:
return _internal_process(data)
# 内部関数は任意
def _internal_process(data):
return {"result": data}よくある質問(FAQ)
型チェックに関するよくある疑問にお答えします。
A: VSCode使うならPyright推奨。高速でリアルタイムチェック。既にmypy使用中なら無理に変えなくてOK。
A: 不要。公開APIや複雑な関数から始めればOK。段階的に追加していく。
A: 使えます。django-stubsインストール + 設定緩和で快適。reportMissingImports = falseが重要。
A: 遅くなりません。型ヒントは実行時には完全に無視されます(静的チェックのみ)。
A: 最小限ならOK。ただし理由をコメントで書く。乱用は避ける。
A: Pyrefly, tyが登場。10-20倍高速だが、まだ実験段階。Pyrightが現時点で最も実用的。出典: Comparing Python's New Rust-Based Type Checkers
参考文献・関連リンク
より詳しく学びたい方のための公式ドキュメント・解説記事をご紹介します。
他の記事を読む
型チェックの導入が完了したら、他のPython開発ツールも確認しましょう。
サンプルリポジトリ
Pyright + django-stubsの実際の設定を公開しています。そのままコピーして使えます。
GitHubで見る

まだコメントはありません。最初のコメントを残しませんか?