ワンクリックで
python-quality
Python coding patterns, idioms, and quality standards for claude-code-discord-bridge development
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Python coding patterns, idioms, and quality standards for claude-code-discord-bridge development
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
ccdb のマイナー/メジャーリリース手順。「v1.4.0としてリリースして」等と言われたときに使う。
Security checklist specific to claude-code-discord-bridge — subprocess injection, env leaks, input validation
Enforce test-driven development — write tests FIRST, then implement. Mandatory for new features and bug fixes.
Testing patterns for claude-code-discord-bridge — pytest, async testing, mocking Discord objects, TDD workflow
Step-by-step guide to add a new discord.py Cog to the framework
Run full verification pipeline (lint, format, test, security) before committing
| name | python-quality |
| description | Python coding patterns, idioms, and quality standards for claude-code-discord-bridge development |
Coding standards and Pythonic patterns for claude-code-discord-bridge development. Based on PEP 8, modern Python 3.10+ idioms, and project conventions.
from __future__ import annotations # Required in EVERY file
# Good: Full type annotations
async def run_claude_in_thread(
thread: discord.Thread,
runner: ClaudeRunner,
repo: SessionRepository,
prompt: str,
session_id: str | None,
) -> str | None:
...
# Bad: Missing annotations
async def run_claude_in_thread(thread, runner, repo, prompt, session_id):
...
# Good: Modern syntax
def process(value: str | None) -> dict[str, list[int]]:
...
# Bad: Old-style typing
from typing import Optional, Dict, List
def process(value: Optional[str]) -> Dict[str, List[int]]:
...
from dataclasses import dataclass, field
@dataclass
class SessionState:
session_id: str | None = None
thread_id: int = 0
accumulated_text: str = ""
active_tools: dict[str, discord.Message] = field(default_factory=dict)
import contextlib
# Discord API calls that may fail: suppress gracefully
with contextlib.suppress(discord.HTTPException):
await message.add_reaction(emoji)
# Business logic: handle explicitly
try:
async for event in runner.run(prompt):
process(event)
except Exception:
logger.exception("Failed to run CLI for thread %d", thread.id)
await thread.send(embed=error_embed("An unexpected error occurred."))
import logging
logger = logging.getLogger(__name__)
# Good
logger.info("Starting CLI: %s", " ".join(args[:6]))
logger.warning("Session %s timed out after %ds", session_id, timeout)
logger.exception("Unexpected error in thread %d", thread.id)
# Bad — never use print() in library code
# Always use create_subprocess_exec (not shell-based alternatives)
process = await asyncio.create_subprocess_exec(
*args,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
)
# Timeout handling
try:
await asyncio.wait_for(process.wait(), timeout=5)
except TimeoutError:
process.kill()
# Cleanup with try/finally
try:
async for event in self._read_stream():
yield event
finally:
await self._cleanup()
Enforced by ruff (I rule):
# 1. Standard library
import asyncio
import logging
import re
# 2. Third-party
import discord
from discord.ext import commands
# 3. Local (relative)
from ..claude.runner import ClaudeRunner
from ..claude.types import MessageType
# Module-level, UPPER_SNAKE_CASE
DEBOUNCE_MS = 700
STALL_SOFT_SECONDS = 10
MAX_MESSAGE_LENGTH = 2000
# Frozen sets for immutable collections
_STRIPPED_ENV_KEYS = frozenset({"DISCORD_BOT_TOKEN", "CLAUDECODE"})
_ (e.g., _run_helper.py)__init__.py: Public API exports only, no logicProject uses ruff with these rule sets (see pyproject.toml):
| Rule | Purpose |
|---|---|
| E | pycodestyle errors |
| F | pyflakes |
| W | pycodestyle warnings |
| I | isort (import sorting) |
| N | pep8-naming |
| UP | pyupgrade (modern syntax) |
| B | flake8-bugbear |
| A | flake8-builtins |
| SIM | flake8-simplify |