一键导入
py-complexity
Reduce cyclomatic and cognitive complexity in Python code. Break down complex functions, simplify control flow, and track complexity trends over time.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Reduce cyclomatic and cognitive complexity in Python code. Break down complex functions, simplify control flow, and track complexity trends over time.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Set up git pre-commit hooks to run ruff, mypy, and basedpyright before commits. Use when configuring automated quality checks in git workflow.
Configure ruff, mypy, and basedpyright for Python 3.13 projects. Use when setting up linters and type checkers in pyproject.toml and pyrightconfig.json.
Detect and remove dead code, duplicate code, and unused imports. Consolidate similar code patterns into parametrized functions.
Modernize Python codebases - migrate pip to uv, upgrade syntax to Python 3.13+, replace deprecated patterns, and update tooling to current best practices.
Orchestrate comprehensive Python refactoring - coordinates security, complexity, testing, code health, and modernization skills to systematically improve code quality.
Security vulnerability detection and remediation for Python codebases. Identifies SQL injection, hardcoded secrets, weak cryptography, and other OWASP vulnerabilities.
| name | py-complexity |
| description | Reduce cyclomatic and cognitive complexity in Python code. Break down complex functions, simplify control flow, and track complexity trends over time. |
| status | stable |
Reduce code complexity to improve maintainability and understandability.
Effective use of context windows.
Add to [dependency-groups] dev: "radon", "lizard", "xenon", "wily"
Permissions: Run py-quality-setup first to configure .claude/settings.local.json with all needed tool permissions.
# Key commands
radon cc . -n C # Functions with complexity ≥11
lizard -C 15 . # Cognitive complexity warnings
radon mi . -n B # Maintainability index <65
wily build . # Initialize tracking (one-time)
wily diff HEAD~10 # Compare trends
scc --by-file --ci # Optional: code statistics (called 'sccount' on openSUSE)
Use Explore agent to find these complexity-increasing patterns:
Magic numbers and strings:
grep -rE '\b[0-9]{2,}\b' --include='*.py' for multi-digit numbersRepetitive field operations:
if obj.field: obj.field = func(obj.field)Repeated complex type definitions:
Literal["a", "b", "c"] | None repeated across functions/classesgrep -r 'Literal\[' --include='*.py' then look for duplicatesLong if/elif chains:
Deeply nested code:
Break complex functions into focused sub-functions:
# BEFORE - 20+ lines, complexity: 15
def process_order(order: dict) -> bool:
# Validation, payment, confirmation logic all mixed
# AFTER - Each function <5 lines, complexity: <5
def process_order(order: dict) -> bool:
return is_valid_order(order) and process_payment(order) and complete_order(order)
Replace nested conditions with early returns:
# BEFORE - Deep nesting
if user:
if user.get("active"):
if user.get("verified"):
return True
return False
# AFTER - Guard clauses
if not user or not user.get("active") or not user.get("verified"):
return False
return True
Replace if/elif chains with dictionaries:
# BEFORE - Nested conditionals (complexity: 7)
if customer == "gold" and total > 1000: return 0.20
elif customer == "gold": return 0.15
# ... more branches
# AFTER - Lookup table (complexity: 2)
RATES = {("gold", "high"): 0.20, ("gold", "low"): 0.15, ...}
return RATES.get((customer, tier), 0.0)
Extract scattered literals to configuration classes:
# BEFORE - Magic numbers throughout code
if amount < 100: base_fee = 2.50
elif amount < 1000: base_fee = 5.00
if account_type == "premium": return base_fee * 0.5
# AFTER - Configuration class
class FeeConfig:
TIER_SMALL = 100
FEE_SMALL = 2.50
PREMIUM_DISCOUNT = 0.5
if amount < FeeConfig.TIER_SMALL:
base_fee = FeeConfig.FEE_SMALL
Benefits: Single source of truth, easy to change, self-documenting, can load from environment
Replace repetitive if-statements with loops over field names:
# BEFORE - 15 similar if-statements (complexity: 9)
if config.email.smtp_host:
config.email.smtp_host = substitute_secret(config.email.smtp_host, secrets)
if config.email.smtp_user:
config.email.smtp_user = substitute_secret(config.email.smtp_user, secrets)
# ... 13 more similar lines
# AFTER - Loop over field list (complexity: 3)
email_fields = ["smtp_host", "smtp_user", "smtp_password", "smtp_from"]
for field in email_fields:
if value := getattr(config.email, field, None):
setattr(config.email, field, substitute_secret(value, secrets))
Pattern: Use getattr/setattr loops for: validation, field clearing, transformation, serialization
Replace repeated complex type annotations with TypeAlias:
# BEFORE - Type repeated 8 times across files
cache_mode: Literal["use", "only", "refresh"] | None
# ... used in 8 different functions, classes
# AFTER - Define once, use everywhere
CacheMode = Literal["use", "only", "refresh"]
CacheModeOptional = CacheMode | None
cache_mode: CacheModeOptional
Placement:
types.py: project-wide types__init__.py: package-wide exportsBenefits: DRY, semantic names, easier to change, reduced typos
radon cc . -n C reports no functions with complexity ≥C (11+)lizard -C 15 . reports no cognitive complexity warningsradon mi . -n B reports no modules with maintainability index <65wily build . initialized for trackingExample: Complexity reduction workflow
1. Measure: radon cc . -n C; lizard -CCN 15 .
2. Found: handlers.py:process_data (complexity D: 25)
3. Apply patterns: Extract functions, guard clauses, lookup tables
4. Result: 4 functions with complexity A-B
5. Track: wily diff HEAD~1 shows 20-point reduction
Example: Apply specialized patterns
# Magic numbers: Search with grep, extract to config class
if amount < 100: fee = 2.50 # BEFORE
if amount < FeeConfig.TIER_SMALL: fee = FeeConfig.FEE_SMALL # AFTER
# Repetitive fields: Replace 15 if-statements with loop
for field in ["smtp_host", "smtp_user", ...]:
if value := getattr(config, field, None):
setattr(config, field, process(value))
# Complex types: Extract repeated Literal types to TypeAlias
CacheMode = Literal["use", "only", "refresh"] # Used 8 times → defined once