python-authoring について
easy-cheese のリポジトリ内で、規約に沿った簡潔で読みやすい Python の変更を行うためのスキルです。コード確認、入力検証、テスト、プロジェクト検査の手順を示します。
主な機能
- 01リポジトリと呼び出し元の確認
- 02境界での検証と型付きデータ
- 03標準ライブラリ優先の指針
- 04Python のスタイルとパッケージ境界
- 05型チェックとテストの手順
活用シーン
- 01範囲を絞った Python の変更
- 02easy-cheese スキルへのコード追加
- 03変更ファイルとバンドルの検証
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ paulnsorensen/ easy-cheese --skill python-authoringインストール後、Claude Code で/python-authoringを入力して読み込まれたか確認します。
詳細
Python の作成
依頼を満たし、easy-cheese の規約に合う、読みやすく最小限の Python の変更を行います。
これはリポジトリ内に限定されたスキルです。.agents/skills/python-authoring/ の下に置き、公開対象の skills/ ツリーに複製したり、agents/openai.yaml を追加したりしないでください。このディレクトリ名を変更する場合は、.gitignore 内の対応する !.agents/skills/<dir>/ の行も更新してください。パス一覧は許可リストのため、改名したディレクトリに専用の行がないと、追跡対象から黙って外れます。
次の順序で作業します
- ルート設定、該当するスキル、対象のエクスポート、直接の呼び出し元、近隣の規約を読みます。
- 変更するすべての行を依頼に紐付けられるようにします。オーケストレーション、互換性レイヤー、抽象化、依存関係、将来の柔軟性を独自に追加しないでください。
- コードは該当するパッケージに配置し、バンドルの境界を維持します。
- 信頼できない入力は境界で一度だけ検証し、その後は型付けされた信頼済みデータを扱います。
- 明快で簡潔な Python の構文を選びます。読みづらくなるほどコードを圧縮しないでください。
- この変更で生じた不要なコードと、この変更によって使われなくなったコードだけを取り除きます。
- 変更したファイルを basedpyright で型チェックし、対象を絞ってテストを実行し、影響を受けるバンドルを再ビルドしてから、
just checkを実行します。
ランタイムコードでは標準ライブラリを優先します
- Python 3.12 を対象とします。言語機能と型機能をそのまま使い、旧バージョン向けの互換コードは追加しません。
src/配下のバンドル対象ヘルパーでは、標準ライブラリを既定の依存関係とします。サードパーティ製のランタイム依存関係は純粋な Python であることを必須とし、requirements/runtime.txtに追加します。バンドルのビルドでは、内部および外部のハッシュを一時的な requirements ファイルに解決します。- 新しいバンドルモジュールに PyYAML をインポートするのではなく、既存の JSON 優先、YAML は任意のマニフェスト境界を再利用します。
- 設定済みのサードパーティ製インポートは、対象範囲が限定された例外として扱います。既存のバリデーター、ドキュメントツール、マニフェスト/テスト用のパスでは PyYAML、テストでは pytest を使用します。新しい依存関係には、パッケージと CI の明示的な判断が必要です。
- 手書きの代替実装より、
argparse、json、pathlib、tempfile、shutil、zipfile、collections、itertools、contextlibを優先します。
データを明示的にモデル化して検証します
- 信頼できないテキストは適切な標準ライブラリのパーサーで解析し、期待するコンテナーの形を要求し、必須キーと値の型を確認して、境界で具体的なエラーを発生させます。
- 名前付きフィールドと不変条件によって契約が明確になる場合は、検証済みのマッピングを frozen dataclass またはドメイン値型に変換します。
- マッピングをマッピングのまま扱う必要がある場合に限り、
TypedDictを使用します。静的な形状を記述するものであり、実行時の入力を検証するものではありません。 - 値の集合が限定されている場合は
EnumまたはLiteralを使い、複数の実際の利用者がある構造的インターフェースにはProtocolを使います。 - 関数とパブリックメソッドの境界には、すべて型注釈を付けます。型推論が明らかな場合は、ローカル変数の注釈を省略します。
- 名前付きレコードによって契約が明確になる場合は、構造化された生の辞書を解析境界の外へ渡さないでください。
スキルのパッケージ境界を維持します
- スキルのランタイムは
src/easy_cheese/skills/<skill_name>/に置き、その CLI のインターフェースはcommands.pyで宣言します。 - 複数の既存スキルで同じ動作が必要な場合に限り、コードを
src/easy_cheese/shared/に移します。共有コードは、それを所有する各アーカイブにバンドルします。 - 別のスキルの内部実装をインポートしないでください。各アーカイブには、純粋な Python で構成されたランタイムの依存関係一式を含めます。
- スキル間のオーケストレーションは、リーフヘルパーではなく、それを所有するワークフローの境界に置きます。逆向きの依存関係や循環依存を避けるため、パブリックな契約または永続化された契約を介して連携します。
skills/<skill>/scripts/<skill>.pyzを手作業で編集しないでください。アーカイブの入力を変更した後はjust wedge-buildを実行し、コミット済みアーカイブの検証にはjust wedge-checkを実行します。- CLI モジュールは薄く保ちます。
argvを受け取り、整数のステータスを返し、診断を stderr に出力し、0 以外の終了コードで失敗を伝播します。 .github/scripts/のバリデーターは読み取り専用に保ちます。検査と報告のみを行い、ワークスペースを変更しません。
簡潔で読みやすい Python を優先する
- 形状に基づくディスパッチが適切な場合は
matchを使い、二択の判断にはシンプルなifを使います。 - 安定したコマンドから関数へのディスパッチにはハンドラーマッピングを使います。分岐が 1 つか 2 つしかない場合にレジストリを作成しないでください。
- 代入式は、計算の繰り返しをなくす場合、またはループ条件を明確にする場合にのみ使います。
- 純粋なコレクションの検索や変換には
any、all、内包表記、ジェネレーター式を使います。状態の保持、副作用、または明確な早期終了が必要な場合はループを使います。 - 結果が一度だけ消費される場合は、ジェネレーターを優先します。
- 手動でのインデックス操作、文字列の組み立て、後始末、パス操作の代わりに、
enumerate、直接反復、f 文字列、コンテキストマネージャー、pathlibを使います。 - 名前を付けた意図的なエラーのみを無視します。裸の
exceptを使ったり、Exceptionを握りつぶしたり、失敗時に空のデフォルト値を返したり、contextlib.suppress(Exception)を使ったりしないでください。 - 新しいトップレベル関数は、分割すると不自然になる一連のアルゴリズムが明確な場合を除き、40 行以内にします。
- 冗長な足場コードより明快な式を 1 つ使うことを優先しますが、中間の名前で意図が伝わる場合は、密な式を分割します。
仕上げる前にコードの不要な冗長さを取り除く
- コードを言い換えているだけの説明コメントや docstring を削除します。自明でない理由や公開 API のドキュメントは残します。
- 現在のタスクで必要な場合を除き、具体的な利用箇所が 1 つしかない抽象化は削除します。
- 値にはコンテナーや実装の型ではなく、ドメインの概念に基づいた名前を付けます。
- 繰り返しの多いテストは動作ごとにまとめます。入力のバリエーションだけを変えた浅いテストは追加しないでください。
- 抑制を追加するのではなく、根本にある lint の問題を修正します。
basedpyright で型チェックする
- 仕上げる前に
basedpyright <changed .py files>を実行します(バイナリがない場合はuvx basedpyrightを使います)。変更したファイルでエラーと警告がゼロになる必要があります。 - リポジトリの設定は
pyproject.tomlの[tool.basedpyright]にあります。インクルードパス、pythonVersion = "3.12"、および公開済み wheel のrequires-python >=3.11に準拠するためにsrc/easy_cheese_schemasを 3.11 に固定する実行環境が設定されています。typeCheckingModeは意図的に未設定です。basedpyright はデフォルトでrecommendedを使用し、すべてのルールをエラー/警告に分けて有効にするため、failOnWarningsによって警告がある場合も全体の実行が失敗します。 - リポジトリ全体は basedpyright のチェックに合格しており、
just typecheck(just check、just ci、および validate ワークフローに組み込まれています)はエラーと警告がゼロであることを求めます。変更によって表面化した診断は、仕上げる前にすべて自分で修正してください。既存のベースラインも、先送りできる未処理項目もありません。インポートは.venv-typingに対して解決されます。just typecheck-installはrequirements/typing.txtからこの環境を(再)作成します。 - basedpyright は標準の pyright より厳格です。追加ルールもここでは必須です。意図的に無視する関数呼び出しの戻り値は
_に代入し(reportUnusedCallResult)、暗黙の文字列連結をまとめ、信頼できない境界から読み取った値は検証済みの型にcastします。 - wheel から除外されているビルド専用モジュールは、型チェッカーが解決できない静的インポートではなく、
importlib.import_moduleとcastで型付けしたgetattrを使って読み込みます。 - 型は発生源で修正します。抑制が本当に避けられない場合は、ルールを指定した
# pyright: ignore[ruleName]を使います。裸の# type: ignoreやファイル全体に適用する切り替えは使わないでください。スコープが指定されていない抑制はreportIgnoreCommentWithoutRuleによって検出されます。 - ツールに機械可読な診断が必要な場合は
--outputjsonを使います。GitHub Actions では、CLI が CI を検出して追加のフラグなしで PR にインライン注釈を出力します。 - 終了コードを正確に読み取ります。0 は問題なし、1 は診断あり、2 は致命的な内部エラー、3 は設定を読み取れない場合、4 は CLI 引数が不正な場合です。2~4 は型の問題ではなくツールの障害として扱い、修正または報告します。
- バイナリは mise で管理され、バージョンが厳密に固定されています(再現性のために厳密な固定を推奨しているのは upstream です)。
pyrightとpyright-langserverのシムは basedpyright を呼び出します。
テストと仕上げ
- 観察可能な動作と、それが重要な理由をテストしてください。実装が壊れていても通る可能性のあるアサーションは追加しないでください。
- ファイルシステムのテストは
tmp_pathまたは同等の一時ディレクトリ内で実行してください。ユーザーのパス、リポジトリ外の状態、ネットワークアクセス、自動読み込みされた pytest プラグインには依存しないでください。 - まず、影響を受ける範囲を絞ったテストを実行してください。範囲を絞った pytest とブラウザーのコマンドは、再ビルドせずにコミット済みの
skills/<skill>/scripts/<skill>.pyzアーカイブを実行します。アーカイブの分離をテストする際は、リポジトリのインポートを利用できない状態にしてください。 - アーカイブの入力に変更を加えた後は、
just wedge-buildを実行し、範囲を絞ったテストでアーカイブを実行する前にjust wedge-checkを実行してください。生成されたランタイムソースに変更を加えた場合は、just update-generatedを実行してください。 - プロジェクトの最終チェックとして
just checkを実行してください。
完了チェック
以下を確認してください。
- ランタイムのインポートが、標準ライブラリ優先かつサーフェスごとの依存関係ポリシーに従っている。
- 境界の入力が一度だけ検証され、適切な信頼済み表現に変換されている。
- コードが、担当するスキルのソースまたは正当な理由のある共有モジュールに置かれている。
- 該当する場合、コマンド登録、生成されたランタイムソース、コミット済みアーカイブが入力と一致している(
scripts/runtime_gates.py、just wedge-check)。 - CLI とバリデーターの失敗が明確に示され、読み取り専用のバリデーターが読み取り専用のままであり、テストが外部環境に依存していない。
- 暗黙の失敗、推測に基づく抽象化、説明的なコメント、不要なローカル注釈、無関係なクリーンアップが残っていない。
- 変更した Python ファイルが、エラーと警告なしで basedpyright に合格している。
- 新たに実行した
just checkが合格している。
コメント
Markdown 対応