- name
- python-coding
- description
- Pythonコードの新規実装・修正・レビュー時に、PEP 8/257/484、型ヒント、docstring、単一責任、可読性を重視した一貫したコーディング方針を適用する。テストはプロジェクトに明記された方針と既存テストの流儀に従い、どちらも無ければpytest準拠で書く。例外、標準ライブラリの慣用、importの構成、設定値と秘密情報の扱いの指針を含む。Pythonのモジュール、クラス、関数、テストを作成または変更する際に使用する。
- license
- MIT
- metadata
- {"version":"1.1.0"}
# python-coding: Python コーディングの方針
> **skill version**: 1.1.0
セッション内で初めて本スキルを使用するときは「python-coding スキル v1.1.0 を使用します」と宣言する。
## 方針の優先順位
本スキルの規定は**既定**であり、プロジェクトの規約を上書きしない。次の順で決める。
1. **プロジェクトに明記された規約。** エージェント向けの指示書(`AGENTS.md` など)、貢献者向けの文書、lint・整形・型検査・テストの設定ファイル。
2. **既存コードの流儀。** 同じプロジェクトの既存コードとテストが採っている書き方。同じプロジェクトの中で流儀を混ぜない。
3. **本スキルの既定。** 以降の各節はこれにあたる。
1と2が矛盾すれば1に従う。
## 実装基準
- PEP 8に従い、読みやすく一貫したコードを書く。
- クラスおよび公開関数・メソッドには、PEP 257に沿ったdocstringを書く。
- 引数・戻り値には、設計を明確にできる場合にPEP 484準拠の型ヒントを付ける。意図的に多様な入力を許容する場合は、無理に不正確な型注釈を付けない。
対象の Python 版をプロジェクトの宣言(`requires-python`、`.python-version`、CI の設定)で確かめ、それより新しい構文を使わない。3.10 以上なら組み込み型と `|` の記法(`list[int]`、`X | None`)を使う。`Any` は最後の手段とし、使うなら理由をコメントで添える。
- 意味のある構造には、素の dict やタプルではなく dataclass・NamedTuple・Enum・TypedDict を使い、意図を型で示す。
- 単一責任を守り、機能単位で関数・クラス・モジュールを分割する。
- 1ファイルは原則1000行以内を目標にし、超える場合は責務で分割できないか検討する。
- 自明でない処理には、**なぜ**その処理を行うかを説明する短いコメントを添える。docstringと同じ内容は繰り返さない。
## 例外の扱い
- 具体的な例外型を送出する。組み込みの例外で意味が合えばそれを使い、ライブラリやアプリケーションの境界では独自の例外を定義する。
- 捕捉する範囲は必要な例外型に絞る。裸の `except` や広すぎる捕捉を書かず、捕まえたら処理するか再送出する。
- 捕まえ直して別の例外を送出するときは、原因を連鎖させる(`raise ... from e`)。
- 不正な入力は入口で早く失敗させる。握りつぶして処理を続行しない。
## 標準ライブラリの慣用
- パス操作は `pathlib` を使う。
- 文字列の整形は f-string を使う。
- ファイルの読み書きは文字コードを明示する(`encoding="utf-8"` など)。
- ファイル・接続などの資源は `with` で閉じる。
- 外部コマンドは `subprocess.run` にリスト引数で渡し、シェルを経由しない。
- 可変な既定引数(list・dict など)を書かない。既定は `None` にして関数内で生成する。
- 診断出力は `logging` を使う。`print` は利用者に見せるための CLI の出力に限る。
## モジュール構成と import
- import はファイルの先頭にまとめ、標準ライブラリ→サードパーティ→自プロジェクトの順に並べ、絶対 import で書く。
- ワイルドカード import(`from x import *`)を書かない。
- 実行の入口は `if __name__ == "__main__":` のガードに置き、処理は関数にする。
- 循環 import を避ける。起きたら責務の分割で解消する。
## 設定値と秘密情報
- 秘密情報(鍵・パスワード・トークン)と環境依存の値(URL・パス・接続先)をコードに直書きせず、環境変数や設定ファイルから読む。
- 秘密情報をログ・例外メッセージ・テストのフィクスチャに出さない。テストにはダミー値を使う。
## テストの書き方
### 流儀の決め方
「方針の優先順位」をテストに当てはめ、次の順で決める。
1. **プロジェクトに明記された方針。** 在処は、エージェント向けの指示書、貢献者向けの文書、テストの設定ファイル(pytest なら `pytest.toml` / `pytest.ini` / `pyproject.toml` の pytest の節 / `tox.ini` / `setup.cfg`。あれば従う)、テスト用の依存関係の宣言、CI の設定。
2. **既存テストの流儀。** テストディレクトリの中身を見る(unittest 流か pytest 流か、配置と命名)。流儀が混在していれば、テストの実行手段(ランナー)が前提とする流儀に合わせる。判別できなければ利用者に確認する。
3. **pytest 準拠**(本スキルの既定)。
一度決めた流儀を、同じプロジェクトの中で混ぜない。
### pytest 準拠で書くときの規定
1. 探索規則に合う命名にする。ファイルは `test_*.py`、関数は `test_` で始める。クラスにまとめるなら `Test` で始め、`__init__` を持たせない。
2. 配置は既存の配置に従う。無ければ `tests/` をパッケージの外に置き、対象モジュールの構成を写す。
3. 検証は素の `assert` で書く。unittest 流の assert メソッドは使わない。何と何を比べたかが失敗時に読めるようにし、自明でなければメッセージを添える。
4. 例外の検証は `pytest.raises` で行い、メッセージの照合(`match`)を添える。
5. 同じ形のケースが並ぶなら `pytest.mark.parametrize` にまとめ、ケースごとに識別できる名前を付ける(`ids`)。
6. 準備と後始末は fixture で行う。組み込みの `tmp_path`(テストごとの一時ディレクトリ)・`monkeypatch`(属性・環境変数の一時変更)・`capsys`(標準出力の捕捉)を自作より優先する。
7. 複数のファイルで共有する fixture は `conftest.py` に置く。
8. `unittest.TestCase` を混ぜない。pytest で走るが、fixture の引数注入とパラメータ化が使えず流儀が割れる。
9. 各テストは独立させ、決定的にする。他のテストの実行順や結果に依存しない。ネットワーク・現在時刻・乱数・作業ディレクトリへの書き込みに依存しない。一時領域は `tmp_path` を使う。
10. スキップ・期待失敗の印は理由付きでのみ使う。テストの設定ファイルを新設せず、要るなら提案して確認を得る。
### テストの実行
- プロジェクトの実行手段で**全件**を実行し(pytest 準拠なら既定は `python -m pytest`)、通過・失敗・スキップの件数を報告する。対象を絞った実行だけで「通った」としない。
- テストを先に書く進め方(テスト駆動開発)を採るかどうかは利用者の方針であり、本スキルは定めない。採る場合はその手順に従う。
## 作業手順
1. 既存のプロジェクト規約、依存関係、テスト構成(テストの流儀と道具立てを含む)を確認する。
2. 影響範囲を最小に保って実装または修正する。
3. 変更したPythonファイルの構文確認と、(存在するならば)テストを全件実行する。
## 検証の実行
- 文法チェックはpy_compileではなくlinter(ruff等)に任せる。
- 決定論的に可能な検証はツールで行い、LLMエージェントは行わない。検証失敗時のみ解析専任サブエージェントに出力の要点抽出を委譲し、原因分析と修正方針は呼び出し元モデルが行う。
- 既存の lint・整形・型検査の設定と、環境の実行方法(仮想環境・ランナー)をそのまま使う。
- 新しいツール・依存関係・設定ファイルを勝手に足さない。要るなら候補と理由を挙げて確認を得る。
- グローバルな Python 環境へインストールしない。
在 GitHub 查看