smithery/YunosukeYoshino

ty-pro

Python型安?

Installation

$ npx skills add smithery/YunosukeYoshino --skill ty-pro

Also in this package

Other skills from smithery/YunosukeYoshino.

npx skills add smithery/YunosukeYoshino

Browse all from smithery/YunosukeYoshino

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 4,320 B
  • docs SUMMARY.md 151 B

History

  1. First recorded snapshot · 0 installs

SKILL.md

ty-pro: Python Type Safety

tyを使ったPython型チェックと型安全なコード設計。

適用場面

  • 型アノテーションの追加・改善
  • ty型エラーの修正
  • API境界でのバリデーション実装
  • Any/cast/ignore の使用判断

🔄 型エラー修正ワークフロー

型エラー修正進捗:
- [ ] Step 1: ty check実行でエラー特定
- [ ] Step 2: エラー分類(真の問題 vs 抑制候補)
- [ ] Step 3: 修正実装
- [ ] Step 4: ty check再実行で確認

Step 1: エラー特定

uv run ty check src/

Step 2: エラー分類

  • 真の型エラー → 修正
  • 外部ライブラリ起因 → # ty: ignore[rule]で抑制
  • 境界入力 → バリデーション追加

Step 3-4: 修正→確認のループ


コマンド

uv run ty check src/           # 型チェック
uv run ty check path/to/file.py  # 単一ファイル

エラー抑制ポリシー

優先順位

  1. 修正(推奨): 型を正しく書く
  2. ナローイング: isinstance、TypeGuardで絞り込み
  3. 抑制: 外部要因でやむを得ない場合のみ

抑制コメント形式

# ✅ 推奨: ルール指定
result = func()  # ty: ignore[invalid-assignment]

# ✅ 複数ルール
value = data["key"]  # ty: ignore[possibly-unbound, invalid-assignment]

# ⚠️ 最終手段: 全抑制(サードパーティ起因のみ)
result = untyped_lib.call()  # type: ignore

関数単位の抑制

from typing import no_type_check

@no_type_check
def legacy_code():
    # この関数内は型チェックされない
    pass

Any/cast使用ポリシー

Any

  • 禁止: コア・ドメインモジュール
  • 許可: 外部境界のみ(API入力、未型付きライブラリ)
  • 必須: 即座にナローイングして精密型へ変換
# ❌ Anyを漏らす
def process(data: Any) -> Any: ...

# ✅ 境界で受けて即変換
def process(data: object) -> Result:
    validated = parse_input(data)  # object → 精密型
    return handle(validated)

cast

  • 使用前に「なぜnarrowing不可か」を説明できること
  • 理由コメント必須
# ✅ 理由付きcast
# SDK returns untyped but we know it's always int
count = cast(int, sdk.get_count())

境界バリデーションパターン

JSON入力

from typing import TypedDict

class UserInput(TypedDict):
    name: str
    age: int

def validate_user(data: object) -> UserInput:
    if not isinstance(data, dict):
        raise ValueError("Expected dict")
    if "name" not in data or "age" not in data:
        raise ValueError("Missing required fields")
    return {"name": str(data["name"]), "age": int(data["age"])}

TypeGuard

from typing import TypeGuard

def is_string_list(val: object) -> TypeGuard[list[str]]:
    return isinstance(val, list) and all(isinstance(x, str) for x in val)

モダン型機能(3.11+)

機能 用途
Protocol 構造的型付け(インターフェース)
TypedDict JSON/dict契約
Literal 判別ユニオン
NewType ドメインID(UserId等)
Self Fluent API
TypeGuard カスタムナローイング

Anti-Patterns

  • ❌ # ty: ignore を理由なく追加
  • ❌ Anyをコアロジックに漏らす
  • ❌ castを検証なしで使用
  • ❌ 全ファイル抑制(# type: ignoreをファイル先頭に)
  • ❌ 無効なルール名での抑制(typoサプレッション)

設定

pyproject.toml

[tool.ty.rules]
# エラーレベル調整
index-out-of-bounds = "warn"
unused-ignore-comment = "error"  # 不要な抑制を検出

設定優先順位

  1. コマンドラインオプション
  2. ty.toml(プロジェクト)
  3. pyproject.toml の [tool.ty]
  4. ユーザー設定(~/.config/ty/)

References