mcpField
P
python-type-safety

python-type-safety

github.com/full-stack-skills開発3100 回インストール5 週間前に更新
リポジトリ

python-type-safety について

Python 開発者向けに、型注釈、ジェネリクス、プロトコル、型の絞り込みを案内するスキルです。mypy や pyright によるコード検査の設定も扱います。

主な機能

  1. 01公開 API への型注釈
  2. 02再利用可能なジェネリッククラス
  3. 03プロトコルによる構造的インターフェース
  4. 04ガードを使った型の絞り込み
  5. 05厳格な型チェックの設定

活用シーン

  1. 01既存コードへの型ヒント追加
  2. 02再利用可能な型安全ライブラリの設計
  3. 03mypy または pyright のチェック設定

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/full-stack-skills/python-skills --skill python-type-safety

インストール後、Claude Code で/python-type-safetyを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

LICENSE.txt
agents/
openai.yaml
examples/
advanced-usage.md
basic-usage.md
integration.md
references/
details.md

詳細

出典の表示:wshobson/agents の内容を基にしています (MIT License、Copyright (c) 2024 Seth Hobson。ライセンス全文は同じディレクトリの LICENSE.txt を参照してください)。 使用、変更、再配布は MIT ライセンスの条項に従い、著作権表示を保持する必要があります。

日本語の説明

このスキルでは、フルスタック開発に関するベストプラクティスとパターンを案内します。

Python の型安全性

Python の型システムを活用して、静的解析時にエラーを検出します。型注釈は、ツールによって自動的に検証されるドキュメントとして機能します。

このスキルを使用する場面

  • 既存のコードに型ヒントを追加する
  • ジェネリックで再利用可能なクラスを作成する
  • プロトコルを使って構造的なインターフェイスを定義する
  • 厳格なチェックを行うために mypy または pyright を設定する
  • 型の絞り込みとガードを理解する
  • 型安全な API やライブラリを構築する

主な概念

1. 型注釈

関数のパラメーター、戻り値、変数に期待される型を宣言します。

2. ジェネリクス

さまざまな型にわたって型情報を保持する、再利用可能なコードを記述します。

3. プロトコル

継承を使わずに構造的なインターフェイスを定義します(型安全性を備えたダックタイピング)。

4. 型の絞り込み

ガードや条件分岐を使って、コードブロック内で型を絞り込みます。

クイックスタート

def get_user(user_id: str) -> User | None:
    """Return type makes 'might not exist' explicit."""
    ...

# Type checker enforces handling None case
user = get_user("123")
if user is None:
    raise UserNotFoundError("123")
print(user.name)  # Type checker knows user is User here

基本的なパターン

パターン 1:すべての公開シグネチャに注釈を付ける

すべての公開関数、メソッド、クラスに型注釈を付けます。

def get_user(user_id: str) -> User:
    """Retrieve user by ID."""
    ...

def process_batch(
    items: list[Item],
    max_workers: int = 4,
) -> BatchResult[ProcessedItem]:
    """Process items concurrently."""
    ...

class UserRepository:
    def __init__(self, db: Database) -> None:
        self._db = db

    async def find_by_id(self, user_id: str) -> User | None:
        """Return User if found, None otherwise."""
        ...

    async def find_by_email(self, email: str) -> User | None:
        ...

    async def save(self, user: User) -> User:
        """Save and return user with generated ID."""
        ...

CI で mypy --strict または pyright を使用して、型エラーを早期に検出します。既存のプロジェクトでは、モジュールごとのオーバーライドを使って、厳格モードを段階的に有効にします。

パターン 2:最新のユニオン構文を使う

Python 3.10+ では、より簡潔なユニオン構文が利用できます。

# Preferred (3.10+)
def find_user(user_id: str) -> User | None:
    ...

def parse_value(v: str) -> int | float | str:
    ...

# Older style (still valid, needed for 3.9)
from typing import Optional, Union

def find_user(user_id: str) -> Optional[User]:
    ...
パターン 3:ガードによる型の絞り込み

条件分岐を使って、型チェッカーが扱う型を絞り込みます。

def process_user(user_id: str) -> UserData:
    user = find_user(user_id)

    if user is None:
        raise UserNotFoundError(f"User {user_id} not found")

    # Type checker knows user is User here, not User | None
    return UserData(
        name=user.name,
        email=user.email,
    )

def process_items(items: list[Item | None]) -> list[ProcessedItem]:
    # Filter and narrow types
    valid_items = [item for item in items if item is not None]
    # valid_items is now list[Item]
    return [process(item) for item in valid_items]
パターン 4:ジェネリッククラス

型安全で再利用可能なコンテナーを作成します。

from typing import TypeVar, Generic

T = TypeVar("T")
E = TypeVar("E", bound=Exception)

class Result(Generic[T, E]):
    """Represents either a success value or an error."""

    def __init__(
        self,
        value: T | None = None,
        error: E | None = None,
    ) -> None:
        if (value is None) == (error is None):
            raise ValueError("Exactly one of value or error must be set")
        self._value = value
        self._error = error

    @property
    def is_success(self) -> bool:
        return self._error is None

    @property
    def is_failure(self) -> bool:
        return self._error is not None

    def unwrap(self) -> T:
        """Get value or raise the error."""
        if self._error is not None:
            raise self._error
        return self._value  # type: ignore[return-value]

    def unwrap_or(self, default: T) -> T:
        """Get value or return default."""
        if self._error is not None:
            return default
        return self._value  # type: ignore[return-value]

# Usage preserves types
def parse_config(path: str) -> Result[Config, ConfigError]:
    try:
        return Result(value=Config.from_file(path))
    except ConfigError as e:
        return Result(error=e)

result = parse_config("config.yaml")
if result.is_success:
    config = result.unwrap()  # Type: Config

詳細な実例とパターン

詳細なセクション(## Advanced Patterns から始まるもの)は references/details.md にあります。上記の概要だけでは不十分な場合は、そのファイルを参照してください。

ベストプラクティスのまとめ

  1. すべての公開 API に注釈を付ける - 関数、メソッド、クラス属性
  2. T | None を使う - Optional[T] よりも最新のユニオン構文を使用する
  3. 厳格な型チェックを実行する - CI で mypy --strict を使用する
  4. ジェネリクスを使う - 再利用可能なコードで型情報を保持する
  5. プロトコルを定義する - インターフェイスに構造的型付けを使用する
  6. 型を絞り込む - ガードを使って型チェッカーを支援する
  7. 型変数に制約を設ける - ジェネリクスを適切な型に制限する
  8. 型エイリアスを作成する - 複雑な型に分かりやすい名前を付ける
  9. Any を最小限にする - 具体的な型またはジェネリクスを使用する。Any は、本当に動的なデータや、型付けされていないサードパーティーコードとの連携に適しています
  10. 型を使ってドキュメント化する - 型は検証可能なドキュメントです

対応範囲

✅ 得意なこと
  • フルスタック開発に関するベストプラクティス
  • コードアーキテクチャの設計案内
  • パフォーマンス最適化の提案
⚠️ 追加情報が必要なこと
  • 具体的なプロジェクトのコンテキスト
  • 技術スタックの情報
❌ 対応範囲外
  • 技術分野以外のビジネス上の意思決定
  • 具体的なコードの実装(案内のみ提供)

ワークフロー

Step 1: 要件分析

プロジェクトの要件と技術的な制約を理解します

Step 2: アーキテクチャ設計

システムアーキテクチャとコンポーネントの分割を設計します

Step 3: 実装の案内

具体的な実装の提案とコードパターンを提供します

Step 4: コードレビュー

コードの品質とベストプラクティスの遵守状況を確認します

Step 5: 最適化の提案

パフォーマンスの最適化と改善の提案を行います

注意点

1. 過剰設計

単純なケースでは、複雑なデザインパターンの使用を避けます

2. パフォーマンスの軽視

特に本番環境では、パフォーマンスの最適化を軽視しないでください

3. セキュリティへの配慮

常にセキュリティとデータ保護を考慮してください

4. テストカバレッジ

特に境界ケースについて、十分なテストカバレッジを確保してください

5. ドキュメントのメンテナンス

ドキュメントをコードと同期させて更新してください

コメント