python-development について
Developer Hub、Python Specialist、wxPython Specialist エージェント向けの Python 参考スキルです。バージョン情報に加え、パッケージ化、wxPython の UI、テスト、アクセシビリティ、よくある問題を扱います。
主な機能
- 01Python バージョンのリファレンス
- 02pyproject.toml と PyInstaller の解説
- 03wxPython のレイアウトとイベントの指針
- 04テストとログの例
- 05デスクトップアクセシビリティの指針
活用シーン
- 01Python バージョンの機能確認
- 02Python アプリのパッケージ化
- 03wxPython レイアウトの設計
- 04デスクトップアクセシビリティの確認
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ community-access/ accessibility-agents --skill python-developmentインストール後、Claude Code で/python-developmentを入力して読み込まれたか確認します。
詳細
Python 開発スキル
Developer Hub、Python Specialist、wxPython Specialist エージェント向けの参考データです。
Python バージョン早見表
| バージョン | 主な機能 | EOL |
|---|---|---|
| 3.10 | match/case、X | Y のユニオン、ParamSpec | 2026年10月 |
| 3.11 | 例外グループ、Self 型、tomllib、CPython の高速化 | 2027年10月 |
| 3.12 | 型パラメーター構文 def f[T]()、@override、f-string のネスト | 2028年10月 |
| 3.13 | 実験的なフリースレッドモード、エラーメッセージの改善 | 2029年10月 |
| 3.14 | async pdb.set_trace_async()、テンプレート文字列(PEP 750) | 2030年10月 |
pyproject.toml のひな形
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "my-app"
version = "1.0.0"
requires-python = ">=3.10"
dependencies = []
[project.optional-dependencies]
dev = ["pytest>=8.0", "ruff>=0.6", "mypy>=1.11"]
[project.scripts]
myapp = "my_app.__main__:main"
[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = "-ra --strict-markers"
[tool.ruff]
target-version = "py310"
line-length = 100
[tool.ruff.lint]
select = ["E", "F", "W", "I", "N", "UP", "B", "SIM", "TCH"]
[tool.mypy]
python_version = "3.10"
strict = true
PyInstaller 早見表
単一ファイルモード
exe = EXE(pyz, a.scripts, a.binaries, a.zipfiles, a.datas,
name='MyApp', console=False, icon='icon.ico')
単一フォルダーモード
exe = EXE(pyz, a.scripts, exclude_binaries=True,
name='MyApp', console=False, icon='icon.ico')
coll = COLLECT(exe, a.binaries, a.zipfiles, a.datas, name='MyApp')
よく使われる隠しインポート
pkg_resources.externaccessible_output2(アクセシビリティ対応のデスクトップアプリ向け)keyring.backends(認証情報の保存向け)platformdirshttpx._transports/httpcore._backendsencodings(常に必要)
wxPython 早見表
Sizer チートシート
| Sizer | 使用する場面 |
|---|---|
wx.BoxSizer(wx.VERTICAL) | 項目を上から下へ並べる |
wx.BoxSizer(wx.HORIZONTAL) | 項目を左から右へ並べる |
wx.GridBagSizer(vgap, hgap) | ラベルとコントロールを使ったフォームレイアウト |
wx.FlexGridSizer(rows, cols, vgap, hgap) | 均等なグリッドレイアウト |
wx.WrapSizer | 折り返しのあるフローレイアウト |
wx.StaticBoxSizer(wx.VERTICAL, parent, "Label") | 枠線付きのコントロールグループ |
スレッドセーフな GUI 更新
# From worker thread:
wx.CallAfter(self.update_status, "Done")
wx.PostEvent(self, CustomEvent(data=result))
# NEVER do this from a worker thread:
self.status_bar.SetStatusText("Done") # CRASH or CORRUPTION
標準 ID
| ID | 用途 |
|---|---|
wx.ID_OK | OK ボタン |
wx.ID_CANCEL | キャンセルボタン |
wx.ID_SAVE | 保存操作 |
wx.ID_OPEN | 開く操作 |
wx.ID_EXIT | 終了/閉じる |
wx.ID_HELP | ヘルプ操作 |
wx.ID_NEW | 新規ドキュメント |
wx.ID_UNDO / wx.ID_REDO | 元に戻す/やり直す |
イベントの種類
| イベント | 発生条件 |
|---|---|
wx.EVT_BUTTON | ボタンのクリック |
wx.EVT_MENU | メニュー項目の選択 |
wx.EVT_CLOSE | ウィンドウを閉じる要求 |
wx.EVT_SIZE | ウィンドウのサイズ変更 |
wx.EVT_TIMER | タイマーの発火 |
wx.EVT_TEXT | テキストコントロールの内容変更 |
wx.EVT_LIST_ITEM_SELECTED | リスト項目の選択 |
wx.EVT_TREE_SEL_CHANGED | ツリー選択の変更 |
wx.EVT_UPDATE_UI | UI 状態の更新チェック |
よくある落とし穴
Python
- 変更可能なデフォルト引数:
def f(items=[])は呼び出し間で同じリストを共有します。Noneを使い、関数内で作成してください。 - 遅延束縛クロージャ: ループ内の
lambda: xは値ではなく変数をキャプチャします。lambda x=x: xを使ってください。 - 循環インポート: インポートを関数内に移す、
TYPE_CHECKINGブロックを使う、またはモジュール構成を見直してください。 - データクラス外での
field():field()は@dataclassクラス内でのみ有効です。それ以外では通常の型アノテーションを使ってください。 isと==:isは同一性を、==は等価性を確認します。isはNone、True、Falseにのみ使ってください。- ループ内での文字列連結: 代わりに
"".join()またはio.StringIOを使ってください。
wxPython
- ワーカースレッドからの GUI 操作: 必ず
wx.CallAfter()またはwx.PostEvent()を使ってください。 event.Skip()の欠落: ほかのハンドラーが呼び出されません。イベントを意図的に消費する場合を除き、event.Skip()を呼び出してください。- タイマーの停止忘れ: 破棄後のコールバックを防ぐため、
EVT_CLOSEハンドラー内でタイマーを停止してください。 - AUI の未初期化解除: クローズハンドラー内で
_mgr.UnInit()を呼び出してください。 - ダイアログの破棄忘れ: コンテキストマネージャー(
with MyDialog(...) as dlg:)を使って自動的にクリーンアップしてください。 - Sizer 項目の親の誤り: Sizer 内のすべてのコントロールは、同じ親パネルを持つ必要があります。
- 絶対位置指定: レイアウトに
SetPosition()やSetSize()を使わないでください。必ず Sizer を使ってください。
クロスプラットフォームのパス
from platformdirs import user_config_dir, user_data_dir, user_cache_dir
config = user_config_dir("MyApp", "MyCompany") # %APPDATA% / ~/Library/... / ~/.config/
data = user_data_dir("MyApp", "MyCompany")
cache = user_cache_dir("MyApp", "MyCompany")
テスト早見表
# Run all tests
pytest
# Run specific test file
pytest tests/test_queue.py
# Run specific test
pytest tests/test_queue.py::test_submit_job -v
# With coverage
pytest --cov=mypackage --cov-report=term-missing
# Stop on first failure
pytest -x
# Show locals on failure
pytest -l
ロギング設定テンプレート
import logging
def setup_logging(level: int = logging.INFO) -> None:
logging.basicConfig(
level=level,
format="%(asctime)s %(name)s %(levelname)s %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
)
# Quiet noisy libraries
logging.getLogger("httpx").setLevel(logging.WARNING)
logging.getLogger("httpcore").setLevel(logging.WARNING)
デスクトップアクセシビリティ早見表
プラットフォーム API の概要
| プラットフォーム | API | Python バインディング | 用途 |
|---|---|---|---|
| Windows | UI Automation (UIA) | comtypes, pywinauto | モダンアプリ、NVDA/Narrator |
| Windows | MSAA / IAccessible2 | comtypes, pywinauto | レガシーアプリ、JAWS |
| macOS | NSAccessibility | pyobjc | VoiceOver |
wxPython アクセシビリティの基本
# Name every control that lacks a visible label
# CORRECT: use StaticText immediately before the control in the sizer
label = wx.StaticText(panel, label="Scan progress:")
# ctrl = wx.Gauge(panel) -- add label to sizer right before ctrl
# WRONG: SetName() is ignored by screen readers
# ctrl.SetName("Scan progress") -- only affects FindWindowByName()
# Tab order follows sizer insertion order; override with:
ctrl2.MoveAfterInTabOrder(ctrl1)
# Keyboard shortcuts via accelerator table
accel = wx.AcceleratorTable([
(wx.ACCEL_CTRL, ord('S'), wx.ID_SAVE),
(wx.ACCEL_CTRL, ord('Q'), wx.ID_EXIT),
])
frame.SetAcceleratorTable(accel)
# Platform-correct button order in dialogs
sizer.Add(dialog.CreateStdDialogButtonSizer(wx.OK | wx.CANCEL))
スクリーンリーダーの操作モデル
スクリーンリーダーは、コントロールを 名前 + ロール + 値 + 状態 として提示します。
| プロパティ | wxPython での設定元 | 例 |
|---|---|---|
| 名前 | 直前の wx.StaticText、label= パラメーター、または SetToolTip() | "スキャンの進捗" |
| ロール | ウィジェットの種類(自動) | ボタン、テキストフィールド、リスト |
| 値 | ウィジェットのコンテンツ | "75%"、"Hello world" |
| 状態 | ウィジェットのフラグ | フォーカス中、無効、チェック済み |
デスクトップのアクセシビリティチェックリスト
- すべてのコントロールにわかりやすい名前が付いている(入力欄には直前の
wx.StaticText、ボタンにはlabel=、画像のみのコントロールにはSetToolTip()を使用) - キーボードのみで操作できる -- すべての操作を Tab/Enter/Space/矢印キーで実行できる
- フォーカスが見える -- フォーカスインジケーターを決して無効にしない
- Tab キーの移動順序が論理的である(通常は上から下、左から右)
- 色だけを情報伝達に使用しない
- ハイコントラストモードに対応している(ハードコードされた色ではなく、システムカラーを使用)
- ダイアログでは、プラットフォームに適したボタン順序にするため
CreateStdDialogButtonSizer()を使用する - AUI ペインをキーボードで操作できる
構造化された監査ルールセット
監査モードが有効になると、エージェントは次の構造化された検出ルールセットを使用します。
| ルールのプレフィックス | エージェント | 対象範囲 | 件数 |
|---|---|---|---|
| WX-A11Y-001..012 | wxpython-specialist | wxPython 固有のパターン(StaticText ラベル、AcceleratorTable、マウスのみのイベント、ダイアログ) | 12 ルール |
| DTK-A11Y-001..012 | desktop-a11y-specialist | プラットフォームレベルの API パターン(名前/ロール/状態/値、フォーカス、UIA/NSAccessibility) | 12 ルール |
| TST-A11Y-001..010 | desktop-a11y-testing-coach | テストカバレッジの不足(自動テスト、スクリーンリーダーのテスト、キーボード操作計画、CI 統合) | 10 ルール |
ルールセットの対象範囲は重複しません。WX は wxPython ウィジェットのパターン、DTK はプラットフォーム API、TST はテストプロセスの不足を対象とします。
エージェントのルーティング
より専門的な支援が必要な場合、このスキルは次のスペシャリストにルーティングします。
desktop-a11y-specialist-- プラットフォーム API の実装、wx.Accessible、カスタムウィジェットのパターン(DTK-A11Y-* 監査ルール)desktop-a11y-testing-coach-- NVDA/JAWS/Narrator のテスト、Accessibility Insights、自動 UIA テスト(TST-A11Y-* 監査ルール)a11y-tool-builder-- ルールエンジンのアーキテクチャ、ドキュメントパーサー、重大度のスコアリング、レポート生成ツール
コメント
Markdown 対応