mcpField
P
python-debugger

python-debugger

github.com/majesticlabs-dev開発50102 回インストール7 週間前に更新
リポジトリ

python-debugger について

python-debuggerは、Python開発者向けに、エラーの再現から原因特定、修正、検証までを案内するスキルです。トレースバック、pdb、ログ、プロファイリング、よくある原因を扱います。

主な機能

  1. 01段階的なデバッグ手順
  2. 02トレースバックの分析
  3. 03再現と切り分けの手法
  4. 04よくあるPythonエラーと修正方法
  5. 05ログとプロファイリングの案内
  6. 06pdbとエラー種類のリファレンス

活用シーン

  1. 01例外の発生箇所の追跡
  2. 02不具合を再現する最小ケースの作成
  3. 03pytestによる修正の検証
  4. 04性能やメモリ問題の調査

インストール

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

$npx skills add https://github.com/majesticlabs-dev/majestic-marketplace --skill python-debugger

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

同梱ファイル

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

references/
debug-checklist.md
pdb-commands.md
python-error-types.md

詳細

Python デバッガー

デバッグのプロセス

  1. エラーを理解する -> 2. 再現する -> 3. 問題を切り分ける -> 4. 根本原因を特定する -> 5. 修正する -> 6. 検証する

ステップ 1:エラーを理解する

トレースバックを読む
Traceback (most recent call last):        <- Read bottom to top
  File "app.py", line 45, in main         <- Entry point
    result = process_data(data)           <- Call chain
  File "processor.py", line 23, in process_data
    return transform(item)                <- Getting closer
  File "transformer.py", line 12, in transform
    return item["value"] / item["count"]  <- Error location
ZeroDivisionError: division by zero       <- The actual error

一般的なエラーの種類については、references/python-error-types.md を参照してください。

ステップ 2:問題を再現する

エラーを引き起こす最小限のテストケースを作成します。次の質問に答えてください。

  • どのような入力が原因でしたか?
  • 毎回発生しますか、それとも断続的に発生しますか?
  • いつから発生し始めましたか?
  • 最近、何が変わりましたか?

ステップ 3:問題を切り分ける

print によるデバッグ
def process_data(data):
    print(f"DEBUG: data type = {type(data)}")
    print(f"DEBUG: data = {data}")

    for i, item in enumerate(data):
        print(f"DEBUG: processing item {i}: {item}")
        result = transform(item)
        print(f"DEBUG: result = {result}")

    return results
pdb を使う
import pdb

def problematic_function(x):
    pdb.set_trace()  # Execution stops here
    # Or use: breakpoint()  # Python 3.7+
    result = x * 2
    return result

pdb のコマンドについては、references/pdb-commands.md を参照してください。

icecream を使う
from icecream import ic

def calculate(x, y):
    ic(x, y)  # Prints: ic| x: 5, y: 0
    result = x / y
    ic(result)
    return result

ステップ 4:よくある根本原因

  • None 値:属性にアクセスする前に戻り値を確認します。if x is None: raise ValueError(...) でチェックします。
  • 型の不一致:型ヒントを追加し、入力を明示的にキャストします。a + b ではなく int(a) + int(b) を使います。
  • 変更可能なデフォルト引数:def f(items=None): を使い、関数内で items = items or [] とします。
  • 循環インポート:関数内で遅延インポートを使います:from .module import Class
  • async/await:await がないと、結果ではなくコルーチンが返されます。
  • キー/インデックスのエラー:辞書には .get(key, default) を使い、リストでは len() を確認します。
  • スコープの問題:global/nonlocal の宣言や、ループ内でのクロージャ変数のキャプチャを確認します。
  • エンコーディング:open() の呼び出しで encoding="utf-8" を指定します。
  • 浮動小数点の精度:比較には decimal.Decimal または math.isclose() を使います。
  • リソースリーク:ファイル、接続、ロックには with 文を使います。

ステップ 5:修正のパターン

防御的プログラミング
def safe_divide(a, b):
    if b == 0:
        raise ValueError("Cannot divide by zero")
    return a / b

def safe_get(data: dict, key: str, default=None):
    return data.get(key, default)
入力の検証
def process_user(user_id: int, data: dict) -> dict:
    if not isinstance(user_id, int) or user_id <= 0:
        raise ValueError(f"Invalid user_id: {user_id}")

    required_fields = ["name", "email"]
    missing = [f for f in required_fields if f not in data]
    if missing:
        raise ValueError(f"Missing required fields: {missing}")
例外処理
import logging

logger = logging.getLogger(__name__)

def fetch_user_data(user_id: int) -> dict:
    try:
        response = api_client.get(f"/users/{user_id}")
        response.raise_for_status()
        return response.json()
    except requests.HTTPError as e:
        logger.error(f"HTTP error fetching user {user_id}: {e}")
        raise
    except requests.ConnectionError:
        logger.error(f"Connection failed for user {user_id}")
        raise ServiceUnavailableError("API unavailable")

ステップ 6:修正を検証する

import pytest

def test_transform_handles_zero_count():
    """Verify fix for ZeroDivisionError."""
    data = {"value": 10, "count": 0}

    with pytest.raises(ValueError, match="count cannot be zero"):
        transform(data)

def test_transform_normal_case():
    """Verify normal operation still works."""
    data = {"value": 10, "count": 2}
    result = transform(data)
    assert result == 5

デバッグツール

ロギングの設定
import logging

logging.basicConfig(
    level=logging.DEBUG,
    format="%(asctime)s %(name)s %(levelname)s: %(message)s",
    handlers=[
        logging.FileHandler("debug.log"),
        logging.StreamHandler(),
    ],
)
プロファイリング
# Time profiling
import cProfile
cProfile.run("main()", "output.prof")

# Memory profiling
from memory_profiler import profile

@profile
def memory_heavy_function():
    # ...
rich を使った見やすい出力
from rich.traceback import install
install(show_locals=True)  # Enhanced tracebacks

参考資料

WebSearch を使う場面

  • 分かりにくいエラーメッセージ
  • ライブラリ固有のエラー
  • バージョンの互換性に関する問題
  • ドキュメントに記載されていない動作

コメント