スキル一覧に戻る
gigaverse-app

pythonista-typing

by gigaverse-app

0🍴 0📅 2026年1月24日
GitHubで見るManusで実行

SKILL.md


name: pythonista-typing description: Python type annotations and Pydantic best practices. Use when working with types, models, or data structures. Triggers on "type", "types", "typing", "Pydantic", "BaseModel", "dict", "list", "tuple", "annotation", "hint", "Any", "TypedDict", "dataclass", "model", "schema", or when defining function signatures or data models.

Type Annotations and Pydantic Best Practices

Core Philosophy

Use Pydantic models for structured data. Use specific types everywhere. Never use Any or raw dicts when structure is known.

Type Annotations

Modern Python Syntax

# CORRECT - Modern Python 3.9+ syntax
def process_data(items: list[str]) -> dict[str, list[int]]:
    results: dict[str, list[int]] = {}
    return results

# WRONG - Old style imports
from typing import Dict, List, Tuple
def process_data(items: List[str]) -> Dict[str, List[int]]:
    ...

NEVER Use Float as Dict Keys

# WRONG - Float precision issues
def group_by_duration(participants) -> dict[float, list[Participant]]:
    groups[1.5] = [p1, p2]
    return groups

# CORRECT - Use Pydantic model
class DurationGroup(BaseModel):
    duration_seconds: float
    participants: list[Participant]

def group_by_duration(participants) -> list[DurationGroup]:
    return [DurationGroup(duration_seconds=1.5, participants=[p1, p2])]

Complex Return Types Must Be Named

# WRONG - Unreadable
def execute_moderation(
    participants: list[Participant],
) -> tuple[BatchResults, dict[str, Optional[Egress]]]:
    pass

# CORRECT - Named model
class ModerationResult(BaseModel):
    batch_results: BatchResults
    egress_statuses: dict[str, Optional[Egress]]

def execute_moderation(participants: list[Participant]) -> ModerationResult:
    pass

Rule of thumb: If you can't read the type annotation out loud in one breath, it needs a named model.

Always Type ALL Parameters

# WRONG - Untyped callback
async def execute_moderation(
    channel_id: str,
    result_enricher=None,  # NO TYPE HINT!
):
    pass

# CORRECT - Use Protocol for callbacks
class ResultEnricher(Protocol):
    def __call__(self, result: VideoModerationResult) -> VideoModerationResult: ...

async def execute_moderation(
    channel_id: str,
    result_enricher: ResultEnricher | None = None,
):
    pass

Be Specific With Collections

# WRONG - What's in the list?
def get_users() -> list:
    return [{"name": "Bob"}]

# CORRECT - Specific types
def get_users() -> list[User]:
    return [User(name="Bob")]

NEVER Use hasattr/getattr as Type Substitutes

# WRONG - Type cop-out
def process(obj: Any):
    if hasattr(obj, "name"):
        return obj.name
    return None

# CORRECT - Use Protocol
class Named(Protocol):
    name: str

def process(obj: Named) -> str:
    return obj.name

Data Structures

Always Use Pydantic Models for Structured Data

# WRONG - Raw dict
def get_video_result() -> dict[str, Any]:
    return {
        "is_appropriate": True,
        "confidence": 0.95,
    }

# CORRECT - Pydantic model
class VideoResult(BaseModel):
    is_appropriate: bool
    confidence: float

def get_video_result() -> VideoResult:
    return VideoResult(is_appropriate=True, confidence=0.95)

TypedDict and dataclasses Are Prohibited

NEVER use TypedDict or dataclasses without explicit authorization.

# WRONG
from typing import TypedDict

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

# WRONG
from dataclasses import dataclass

@dataclass
class UserData:
    name: str
    age: int

# CORRECT - Always use Pydantic
from pydantic import BaseModel

class UserData(BaseModel):
    name: str
    age: int

Tuple Rules

Tuples are acceptable ONLY for simple 2-element pairs:

# CORRECT - Simple pair with type alias
CacheResult = tuple[str | None, bool]  # (value, cache_hit)

def get_from_cache(key: str) -> CacheResult:
    value = cache.get(key)
    return (value, value is not None)

# WRONG - More than 2 elements
def get_user_info() -> tuple[str, int, str, bool]:  # Use a model!
    return ("Alice", 30, "alice@example.com", True)

Never Convert Models to Dicts Just to Add Fields

# WRONG - Breaking type safety
async def analyze_video(...) -> dict[str, Any]:
    result = await llm.ainvoke(...)
    result_dict = result.model_dump()
    result_dict["_run_id"] = run_id  # Now everything is untyped!
    return result_dict

# CORRECT - Extend the model
class VideoModerationResult(BaseModel):
    details: VideoModerationDetails
    run_id: str | None = None

async def analyze_video(...) -> VideoModerationResult:
    details = await llm.ainvoke(...)
    return VideoModerationResult(details=details, run_id=run_id)

Pydantic and External Systems

Writing to External Systems

# WRONG - Manual dict
await mongodb.insert_one({
    "user_id": user_id,
    "created_at": now,
})

# CORRECT - Pydantic model
class UserRecord(BaseModel):
    user_id: str
    created_at: datetime

record = UserRecord(user_id=user_id, created_at=now)
await mongodb.insert_one(record.model_dump(by_alias=True))

Reading from External Systems

# WRONG - Raw dict
doc = await mongodb.find_one({"_id": doc_id})
user_id = doc["user_id"]  # No validation

# CORRECT - Validate through Pydantic
doc = await mongodb.find_one({"_id": doc_id})
record = UserRecord.model_validate(doc)
user_id = record.user_id  # Type-safe, validated

Reference Files

For detailed patterns:

  • For testing typed code, see /pythonista-testing
  • For code review, see /pythonista-reviewing

スコア

総合スコア

60/100

リポジトリの品質指標に基づく評価

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

+10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新がある

0/10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

0/5

レビュー

💬

レビュー機能は近日公開予定です