plugins/python/skills/clean-code-patterns/SKILL.md
# Clean Code Patterns Clean code principles for Python. Code should read like well-written prose. ## Triggers Use this skill when: - Code is hard to read or understand - Function/class does too much - Refactoring is needed - Code review revealed issues - Questions about SOLID, DRY, KISS ## SOLID More details: `${CLAUDE_PLUGIN_ROOT}/skills/clean-code-patterns/references/solid.md` ### S — Single Responsibility ```python # Bad — class does everything class UserService: def create_user(se
npx skillsauth add ruslan-korneev/claude-plugins plugins/python/skills/clean-code-patternsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Clean code principles for Python. Code should read like well-written prose.
Use this skill when:
More details: ${CLAUDE_PLUGIN_ROOT}/skills/clean-code-patterns/references/solid.md
# Bad — class does everything
class UserService:
def create_user(self, data): ...
def send_welcome_email(self, user): ...
def generate_report(self, users): ...
def export_to_csv(self, users): ...
# Good — each class = one responsibility
class UserService:
def create_user(self, data): ...
class EmailService:
def send_welcome_email(self, user): ...
class UserReportGenerator:
def generate(self, users): ...
def export_to_csv(self, users): ...
# Bad — modify code when adding new type
def calculate_discount(order_type: str, amount: float) -> float:
if order_type == "regular":
return amount * 0.1
elif order_type == "premium":
return amount * 0.2
elif order_type == "vip": # Added new type — modified function
return amount * 0.3
# Good — extend through new classes
from abc import ABC, abstractmethod
class DiscountStrategy(ABC):
@abstractmethod
def calculate(self, amount: float) -> float: ...
class RegularDiscount(DiscountStrategy):
def calculate(self, amount: float) -> float:
return amount * 0.1
class PremiumDiscount(DiscountStrategy):
def calculate(self, amount: float) -> float:
return amount * 0.2
# Add VIP — create new class, don't modify existing code
class VIPDiscount(DiscountStrategy):
def calculate(self, amount: float) -> float:
return amount * 0.3
# Bad — subclass violates parent's contract
class Bird:
def fly(self) -> None: ...
class Penguin(Bird):
def fly(self) -> None:
raise NotImplementedError("Penguins can't fly") # LSP violation!
# Good — correct hierarchy
class Bird:
def move(self) -> None: ...
class FlyingBird(Bird):
def fly(self) -> None: ...
class Penguin(Bird):
def move(self) -> None:
self.swim()
# Bad — fat interface
class Worker(Protocol):
def work(self) -> None: ...
def eat(self) -> None: ...
def sleep(self) -> None: ...
class Robot: # Robot doesn't need eat and sleep!
def work(self) -> None: ...
def eat(self) -> None: raise NotImplementedError
def sleep(self) -> None: raise NotImplementedError
# Good — small interfaces
class Workable(Protocol):
def work(self) -> None: ...
class Eatable(Protocol):
def eat(self) -> None: ...
class Robot: # Implements only what's needed
def work(self) -> None: ...
# Bad — dependency on concrete implementation
class OrderService:
def __init__(self):
self.db = PostgresDatabase() # Hard coupling!
self.email = SendGridClient() # Hard coupling!
# Good — dependency on abstractions
class OrderService:
def __init__(
self,
db: DatabaseProtocol,
email: EmailServiceProtocol,
):
self.db = db
self.email = email
More details: ${CLAUDE_PLUGIN_ROOT}/skills/clean-code-patterns/references/principles.md
# Bad — copy-paste
def create_admin(data):
validate_email(data["email"])
validate_password(data["password"])
user = User(**data, role="admin")
db.save(user)
send_welcome_email(user)
return user
def create_moderator(data):
validate_email(data["email"])
validate_password(data["password"])
user = User(**data, role="moderator")
db.save(user)
send_welcome_email(user)
return user
# Good — abstraction
def create_user(data: dict, role: str) -> User:
validate_email(data["email"])
validate_password(data["password"])
user = User(**data, role=role)
db.save(user)
send_welcome_email(user)
return user
# Bad — overengineering
class UserValidatorFactory:
def create_validator(self, user_type: str) -> AbstractValidator:
return self._validators[user_type]()
# Good — simple solution
def validate_user(user: User) -> bool:
return user.email and user.name
# Bad — features "for the future"
class User:
name: str
email: str
phone: str | None # "Might need it"
fax: str | None # "Just in case"
secondary_email: str | None # "Could be useful"
# Good — only what's needed now
class User:
name: str
email: str
More details: ${CLAUDE_PLUGIN_ROOT}/skills/clean-code-patterns/references/code-smells.md
# Bad — 100+ line function
def process_order(order):
# validation (20 lines)
# discount calculation (30 lines)
# inventory update (25 lines)
# notification sending (25 lines)
...
# Good — decomposition
def process_order(order: Order) -> ProcessedOrder:
validated = validate_order(order)
with_discount = apply_discounts(validated)
update_inventory(with_discount)
notify_customer(with_discount)
return with_discount
# Bad — too many parameters
def create_user(name, email, age, city, country, phone, role, department): ...
# Good — Parameter Object
@dataclass
class CreateUserRequest:
name: str
email: str
age: int
city: str
country: str
phone: str
role: str
department: str
def create_user(request: CreateUserRequest): ...
# Bad — deep nesting
def process(user):
if user:
if user.is_active:
if user.has_permission:
if user.balance > 0:
return do_something(user)
return None
# Good — guard clauses (early return)
def process(user):
if not user:
return None
if not user.is_active:
return None
if not user.has_permission:
return None
if user.balance <= 0:
return None
return do_something(user)
More details: ${CLAUDE_PLUGIN_ROOT}/skills/clean-code-patterns/references/naming.md
# Bad
d = 86400
u = get_user()
tmp = calculate()
# Good
SECONDS_IN_DAY = 86400
current_user = get_user()
total_price = calculate()
# Bad
flag = True
status = False
check = user.admin
# Good
is_active = True
has_permission = False
is_admin = user.admin
# Bad — unclear what it does
def process(data): ...
def handle(x): ...
def do_stuff(): ...
# Good — verb + noun
def calculate_total_price(items): ...
def send_welcome_email(user): ...
def validate_order_items(order): ...
/clean:review — analyze code for code smells/clean:refactor <smell> — suggest refactoringtools
# Code Review Skill This skill should be used when the user asks for "code review", "review my changes", "review this PR", "check my code", "pre-merge review", "review diff", or mentions reviewing code quality, implementation correctness, or preparing changes for merge. ## Overview Code review following the **Review Pyramid** methodology — a prioritized approach that focuses on what matters most. ## The Review Pyramid ``` ▲ /|\ 5. Code Style (Nit) ← Least important,
tools
# Architecture Patterns System-level architecture patterns for Python backend projects (FastAPI + SQLAlchemy 2.0). ## Triggers Use this skill when the user: - Designs a new system or major feature - Asks about project structure or module boundaries - Makes data modeling decisions - Designs API contracts - Evaluates architectural trade-offs - Creates or reviews Architecture Decision Records (ADR) - Needs to modernize legacy code ## Abstraction Levels | Plugin | Level | Focus | |--------|----
tools
# Python Typing Patterns Python type annotation patterns without `type: ignore`. Always the correct solution. ## Triggers Use this skill when the user: - Gets mypy/pyright errors - Asks about Python type annotations - Wants to add type hints - Works with generics, protocols, TypeVar ## Main Principle: NEVER type: ignore Every type error has a correct solution. `type: ignore` is: - Masking potential bugs - Disabling type checking - Technical debt More details: `${CLAUDE_PLUGIN_ROOT}/skills/
tools
# Ruff Patterns Knowledge about the ruff linter and patterns for solving errors. **ZERO noqa policy** — always look for the proper solution. ## Triggers Use this skill when the user: - Asks "how to configure ruff" - Gets a ruff error and wants to understand how to fix it - Wants to migrate from black/isort/flake8/pylint - Asks about a specific rule (E501, F401, etc.) ## Main Principle: NEVER USE NOQA **Every ruff error has a proper solution.** Using `# noqa` is: - Hiding the problem, not so