ac-python について
ac-pythonは、Python 3.14プロジェクト向けのコーディングスキルです。Pythonコードの作成、レビュー、テストに携わる開発者を対象に、スタイルや型、設計、テストの指針と参照ファイルを提供します。
主な機能
- 01Python 3.14の指針とPython 3.13の注記
- 02スタイル、型、設計の規約
- 03uv、ruff、mypy/ty、pytestのガイダンス
- 04コーディングとテスト用の参照ファイル
- 05インテグレーションテスト優先の原則
活用シーン
- 01PythonのCLIやサービスを作成
- 02Pythonコードやデータモデルをレビュー
- 03テストとプロジェクトツールを設定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ souliane/ skills --skill ac-pythonインストール後、Claude Code で/ac-pythonを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/oop-and-design.mdstyle-and-typing.mdtesting-and-tooling.md詳細
Python Bible(Python 3.14)
対象: Python 3.14 · 前のバージョン: Python 3.13(末尾のセクション) · ツール: uv · ruff · mypy/ty · prek · pytest
バージョンポリシー
このスキルでは、現在のバージョンの Python だけを扱います。更新する際も、この方針を維持してください。
- メインの内容では、現在の機能リリースを扱います。 現在は Python 3.14 です。3.15 がリリースされたら、同じ編集でメインの内容も 3.15 に移行します。
- バージョンの指定がない文章は現在のバージョンを指し、バージョンのマーカー形式はありません。 Python の機能は機能リリースでのみ追加され、メインの内容は常に現在の機能リリースを扱います。そのため、そこに記載されている内容がそのバージョンより後になることはなく、バージョンの接尾辞を付けても対象がありません。(この点で、兄弟スキルの
ac-djangoのポリシーとは異なります。Django は同じバージョン系列内でも機能を追加するため、バージョンマーカーが必要ですが、Python には不要です。)メインの内容に「Python 3.X 以降では」や「3.13 を使用している場合は」と書かないでください。メインの内容に条件分岐を設けないようにするのが、このルールの目的です。 - 古いバージョン系列については、それぞれ
SKILL.mdの末尾にセクションを 1 つだけ追加し、ほかの場所には記載しません。 参照ファイルには現在のバージョン系列のみを記載し、末尾に追加セクションを設けないでください。現在は## Previous line: Python 3.13が該当します。このセクションには、そのバージョンを使う読者に必要な差分、つまり使えない機能、代わりに使うもの、アップグレード時に変更するものを記載します。 - 更新時の調査順序。 まず
https://docs.python.org/3/whatsnew/とライブラリリファレンスを確認します。次に、Canonical Sources にすでに記載されている情報源を確認します。ブログやニュースレターは最後に、ドキュメントで扱われていない内容を簡潔に確認するために参照します。 - 更新サイクル。 毎年 10 月に新しいバージョン系列がリリースされます。バージョンの指定がない文章を新しい系列に合わせ、末尾のセクションを廃止する系列に置き換え、古いバージョンマーカーを削除します。
公式情報源
- Python ドキュメント:https://docs.python.org/3/
- Ruff ドキュメント:https://docs.astral.sh/ruff/
- uv ドキュメント:https://docs.astral.sh/uv/
- mypy ドキュメント:https://mypy.readthedocs.io/
- pytest ドキュメント:https://docs.pytest.org/
- Typer(CLI):https://typer.tiangolo.com/
参照ファイル(必要に応じて読み込む)
| ファイル | 内容 | 読み込むタイミング |
|---|---|---|
references/style-and-typing.md | スタイル、Python らしいイディオム、型アノテーション、可読性のルール | Python コードの作成またはレビュー時 |
references/oop-and-design.md | OOP パターン、データモデル、ファクトリー、プロパティ、設計原則 | クラス、データモデル、モジュール構成の設計時 |
references/testing-and-tooling.md | テストパターン、pytest のセットアップ、ツール(uv/ruff/mypy/prek)、品質ゲート | テストの作成、プロジェクトのセットアップ、CI の設定時 |
依存関係
単独で使用できます。他のスキルへの依存関係はありません。
ac-django と併用すると、Django 固有のパターンを補完する、汎用的な Python ガイドラインを提供します。
トリガーの QA(リリースゲート)
スキルの変更をリリースする前に、サンプルプロンプトでアクティベーションの動作を検証してください。
- トリガーされるべきプロンプト:
- 「CSV ファイルを処理する CLI スクリプトを作成してください。」
- 「この Python クラスの設計上の問題をレビューしてください。」
- 「この Python マイクロサービスのテストをセットアップしてください。」
- トリガーされるべきでないプロンプト:
- 「Django のモデルフィールドとマイグレーションを追加してください。」
- 「チケット用に git worktree をセットアップしてください。」
- 「プロジェクトのデリバリーワークフローを実装してください。」
動作が過剰または不十分な場合は、リリース前に description の手がかりを調整してください。
例:新しいデータモデルの追加
ユーザーの依頼:「検証機能付きの LoanApplication データモデルを追加してください」
- データモデルのパターンを確認するため、
references/oop-and-design.mdを読み込みます - 型付けの規約を確認するため、
references/style-and-typing.mdを読み込みます - プロジェクトですでに使われている場合は、dataclass または attrs/pydantic を使用します
- 型アノテーションをすべて付け、派生属性には
@cached_propertyを使用します - テストで必要な場合は、ファクトリーを
build_loan_application(...)と命名します - テストファイルのモジュールパスを
tests/内で元のモジュールに合わせます
最優先の指針
Pythonic を第一に
- 汎用的な解決策より、Python らしい解決策を優先します。
- 意図が明確になる場合は、リスト内包表記、ウォルラス演算子(
:=)、itertools、operatorを使用します。 - 一度しか使わない中間変数は避けます。
- 補間値から SQL、HTML、シェルコマンド、テンプレートを構築する場合は、f-string より t-string(
t"..."、PEP 750)を優先します。t-string の評価結果はstrではなく、string.templatelib.Templateです。静的テキストと各Interpolationは分離されたままなので、処理関数は補間値をそれぞれの対象文法に合わせてエスケープできます。安全性を担保するのはその関数です。標準ライブラリにはそのような関数は含まれていないため、ライブラリのものを使うか、自分で作成してください。strが想定される箇所にTemplateを渡すと、エスケープされるのではなくエラーになります。 - zstd には、サードパーティの
zstandardパッケージではなく、標準ライブラリのcompression.zstdを使用します。compression.lzma、compression.bz2、compression.gzip、compression.zlibも、これらのモジュールに推奨されるインポート名です。従来の名前も引き続き使用でき、非推奨ではありません。tarfile、zipfile、shutilは zstd アーカイブの読み書きに対応しています。 as節がない場合は、複数の型を指定するexceptの角括弧を省略します(PEP 758):except TimeoutError, ConnectionRefusedError:。asを使う場合は、引き続き角括弧が必要です。finallyブロックからreturn、break、continueで抜けないでください。処理中の例外が握りつぶされ、コンパイラーがSyntaxWarningを出力します(PEP 765)。
型はドキュメントです
- 最新の型アノテーションをすべての箇所に付けます:
list[str]、str | None、dict[str, int]。 - 繰り返し使う複雑な型には
type文を使用します。 - ダックタイピングは使いません。処理を実行する前に属性の有無を確認している場合は、型ヒントの範囲が広すぎます。型を絞り込んでください。
docstring は使わない — 名前がドキュメントです
- 短く、意図が伝わる関数名と変数名を使います。
- コメントには、明白でない理由だけを書きます。コードを言い換えたり、シグネチャをそのまま繰り返す docstring を書いたりしないでください。
- 長いコメントはコードの設計に問題がある兆候です。説明するのではなく、リファクタリングするか、名前を変更します。複数行のコメントが適切なのは、コードの説明ではなく、明白でない理由を説明する場合だけです。
- 関連する行は、垂直方向の空白でグループ化します。
インポートを整理する
- すべての
import文をファイルの先頭に置きます。 - 関数内でのインポートや、
try...except ImportErrorによるガードは使いません。(リポジトリ固有の慣例では、確立された循環インポートのパターンについて、この規則を緩和できる場合があります。) - すべての依存関係がインストール済みであることを前提とします。
安易な回避策は使わない
- 率直な解決策を選びます。存在しない場合は、設計を見直してください。
- サードパーティ製フレームワークに無理に逆らわず、意図されたパターンに従います。
レビューチェックリスト
スタイル
- 一度しか使わない中間変数がない
- 適切な箇所でリスト内包表記や標準ライブラリの慣用的な書き方を使用している
- 関連するロジックが垂直方向の空白でグループ化されている
型付け
- すべての公開関数とメソッドに最新の型アノテーションが付いている
- 複雑な型や繰り返し使う型に
type文を使用している - ダックタイピングをしていない(適切な型の代わりに
hasattrガードを使用していない)
インポート
- すべてのインポートをファイルの先頭に置いている
-
try...except ImportErrorブロックを使用していない - 関数内でインポートしていない
OOP / 設計
- データモデルを第一級のものとして扱っている(単なる辞書を受け渡していない)
- ファクトリーに
build_...という名前を付けている - アプリケーションロジックをモジュールスコープの関数ではなくメソッドに実装している
- 派生属性に
@property/@cached_propertyを使用している
ベストプラクティス
- タイムゾーン対応の UTC 日時を一貫して使用している
- ブール値のパラメーターの前に
, *,を置いている -
tryブロックとコンテキストマネージャーを最小限にしている(理想的にはそれぞれ 1 行)
アーキテクチャの健全性(モジュールレベル)
変更行だけでなく、差分で変更されたファイル全体に適用します。
- 500 LOC を超えるモジュールがない(関心ごとに分割する)
- モジュールレベルの関数が 10 個を超えるモジュールがない(クラスを使う)
- モジュールレベルの関数には正当な理由がある — デフォルトではクラスのメソッドにする
- 神クラスならぬ神モジュールがない(CLI の配線 + ビジネスロジック + サブプロセス管理など、無関係な関心ごとを単一ファイルに混在させている場合は分割する)
-
pyproject.tomlに、python-boilerplateのベースラインを超える複雑度ルールの抑制(C901、PLR09xx)がない - テストでは、非公開関数をパッチしたりサブプロセスのコマンドリストを検証したりせず、公開インターフェースを通じて動作を検証する
テスト
インテグレーションテストを優先するテスト方針(必須)
正常系にはインテグレーションテストを、エッジケースにはユニットテストを書きます。 テストコード 1 行あたりの信頼性を最大化できます。
- インテグレーションテストでは、実際の(またはそれに近い)I/O を使い、複数のモジュールを組み合わせて動作させます。最も重要なバグ、つまりモジュール間の契約の破損、状態に関する誤った前提、順序の問題を検出できます。モックにするのは、制御できないもの(ネットワーク、外部プロセス、データベース)だけです。
- ユニットテストでは、特定の関数を単独で対象にします。ただし、エッジケースをテストする価値がある場合(エラー処理、境界値、複雑な分岐)に限ります。単純な接着コードはユニットテストしないでください。
- カバレッジを重複させないでください。 ある正常系がすでにインテグレーションテストでカバーされている場合、同じ経路をユニットテストでテストしないでください。ユニットテストでは、インテグレーションテストでは効率よくカバーできない箇所(まれなエラー分岐、特殊なケース)をテストします。
- E2E テスト(ブラウザー、フルスタック)は別枠です。ライブラリやインフラストラクチャのコードではなく、フロントエンドやアプリケーションのテストスイートに配置します。ユーザーに見える動作をエンドツーエンドでテストする場合に記述します。
テストの簡潔さ(必須)
テストは読みやすく、保守しやすいものにする必要があります。冗長なテストは流し読みされ、誤解され、考えずにコピー&ペーストされます。
- 1 つの概念につきアサーション 1 つ。 テストメソッドでは 1 つの動作をテストします。同じ動作の異なる側面を検証する場合は、複数のアサーションを使ってもかまいません。
- コピー&ペーストではなく、フィクスチャでセットアップします。 テストメソッド間でセットアップコードが繰り返されている場合は、フィクスチャの不足か、パラメーター化できる箇所があります。
- コピー&ペーストではなく、パラメーター化します。 入力値と出力値だけが異なる複数のテストでは、
@pytest.mark.parametrizeを使います。1 つの文字列だけが異なる 5 つのテストメソッドは、パラメーター化した 1 つのテストにまとめます。 - メソッドではなく、動作に基づいてテストに名前を付けます。
test_db_import_3よりtest_returns_error_when_db_missingのほうが適切です。 - 不要なモックは使いません。 制御できないもの(ネットワーク、時計、外部プロセス)だけをモックします。過剰なモックはテストを同語反復的にし、コードではなくモックをテストすることになります。
- 入れ子よりフラットな構成にします。 モジュールレベルのテスト関数、または階層の浅いテストクラスを優先します。テストでクラス階層を深く入れ子にしても、価値のない複雑さが増えるだけです。
monkeypatchよりコンテキストマネージャー(with patch(...))を優先します。 コンテキストマネージャーを使うと、モックが必要なスコープを明確に分離できます。monkeypatchは、テストを実際に簡潔にできる場合(環境変数、chdir、テスト本体の実行後も存続するフィクスチャの属性のパッチなど)に限って使用します。
チェックリスト
- テストファイルのパスが
srcのモジュールパスに対応している - テストクラス名とメソッド名が、テスト対象の動作を表している
- 正常系はインテグレーションテストでカバーし、ユニットテストではエッジケースをカバーしている
- インテグレーションテストとユニットテストでカバレッジが重複していない
- 入力値と出力値だけが異なるテストが 3 件以上ある場合、
@pytest.mark.parametrizeを使用している - セットアップが繰り返される箇所ではフィクスチャを使用し、定型コードをコピー&ペーストしていない
- モックは外部境界(サブプロセス、ネットワーク、時計)に限っている
以前のバージョン:Python 3.13
上記の内容はすべて Python 3.14 を対象としています。3.13 では、次の点に注意してください。
- t 文字列は使えません。 SQL/HTML の構築には、対象ライブラリ独自のパラメーター化またはエスケープ処理(
cursor.execute(sql, params)、markupsafe)を使い、f 文字列による補間は決して使わないでください。 compression.zstdは使えません。 サードパーティーのzstandardパッケージが選択肢となります。tarfile/zipfile/shutilでは zstd の読み書きができません。- アノテーションは即時に評価されます。 前方参照には引き続き
from __future__ import annotationsが必要で、annotationlibはありません。代わりにtyping.get_type_hints()を使ってください。メインパスの ruff 設定ではこのインポートが禁止されています(references/testing-and-tooling.mdのlint.flake8-tidy-imports.banned-api."__future__.annotations")。プロジェクトが 3.13 を対象としている間は、このエントリーを削除し、3.14 で復元してください。 - 複数の型を指定する場合、
exceptでは括弧が必要です。次のように記述します。except (TimeoutError, ConnectionRefusedError): - フリースレッド化は実験的な機能であり、公式にはサポートされていません。また、3.14 の約 5~10%よりもはるかに大きなシングルスレッド実行時の性能低下を伴います。
- プロジェクトが 3.13 を対象としている間は、mypy/ty の設定で
python_version/python-versionを"3.13"に固定してください。