coding-standards

📁 sylla-bv/sylla-skills 📅 6 days ago
3
总安装量
3
周安装量
#58870
全站排名
安装命令
npx skills add https://github.com/sylla-bv/sylla-skills --skill coding-standards

Agent 安装分布

amp 3
opencode 3
kimi-cli 3
codex 3
github-copilot 3
claude-code 3

Skill 文档

Python Coding Standards

Sylla-specific standards for the Python data-engine codebase. All rules are settled and enforced in code review. Full rationale and code examples for every rule are in references/standards.md.

How to Apply This Skill

  • For quick lookups (rule name, convention), use the Quick Reference tables below.
  • For rationale, code examples, or edge cases, consult references/standards.md.
  • When reviewing code, run through the Code Smell Checklist at the bottom of this file.

All work must satisfy readability, KISS, DRY, YAGNI, and security — specifically: no eval/exec/pickle, T | None over Optional[T], explicit return types on public functions, and @property for computed attributes.


Quick Reference

Type Annotations

Rule Standard
Optional types T | None — never Optional[T]
Return types on public functions Required
Return types on internal helpers Inferred is acceptable
Computed attributes @property — never get_x() methods
Generics list[str], dict[str, int] — never List, Dict from typing
Datetime datetime.now(timezone.utc) — never datetime.utcnow()

Imports & Modules

Rule Standard
Import location Top of module always
Function-level imports Only to break circular dependencies
Import order stdlib > third-party > local (isort enforced)
Unused imports Remove — never comment out

Functions & Classes

Rule Standard
Docstrings Google-style on public APIs
Max function length ~50 lines — split if longer
Nesting Max 3 levels — use early returns
Abstract base classes ABC + @abstractmethod for shared contracts
Protocols Use for structural typing when ABC is too rigid

Error Handling

Rule Standard
Bare except Banned
Broad except Exception Only at top-level boundaries with logging
Silent except: pass Banned
Logging library structlog with bound loggers
Error messages Include context (IDs, operation name)
Custom exceptions Inherit from domain-specific base, not bare Exception

Async Patterns

Rule Standard
Parallel async calls asyncio.gather(*tasks)
HTTP client httpx.AsyncClient with explicit timeouts
Sync calls in async Banned — use asyncio.to_thread() if unavoidable
Client lifecycle Context managers (async with) for connection pools

Pydantic Models

Rule Standard
Extra fields model_config = ConfigDict(extra="forbid")
Field metadata Field(description="...") on every field
Computed attributes @property — never get_x()
Enums in models Use StrEnum for string enums

Naming

Thing Convention
Files & folders snake_case
Variables & functions snake_case
Classes PascalCase
Constants SCREAMING_SNAKE_CASE
Private attributes Single leading underscore _name
Type variables PascalCase (T, ResponseT)
Boolean variables is_, has_, can_ prefix

Tooling

Tool Config
Black line-length 88, target py311
isort profile “black”, line_length 88
MyPy strict — disallow_untyped_defs = true, warn_return_any = true
Pytest pythonpath = ["."], testpaths = ["tests"]
Flake8 Ignore E203, W503 (Black-incompatible rules)

Code Smell Checklist

Before opening a PR, check:

  • Optional[T] — change to T | None
  • datetime.utcnow() — change to datetime.now(timezone.utc)
  • get_x() method for a simple computed attribute — change to @property
  • Import inside a function body (no circular dependency reason) — move to top of module
  • Function >~50 lines — split it
  • >3 levels of nesting — use early returns
  • Bare except or except: pass — catch specific exceptions, log the error
  • except Exception in non-boundary code — narrow the exception type
  • Magic number/string — extract to SCREAMING_SNAKE_CASE constant
  • typing.List, typing.Dict, typing.Tuple — use built-in list, dict, tuple
  • Missing return type on public function — add explicit annotation
  • eval(), exec(), pickle.loads() — find a safe alternative
  • HTTP request without timeout — add explicit timeout
  • datetime.utcnow() — use datetime.now(timezone.utc)
  • Sync blocking call inside async function — use asyncio.to_thread()
  • N+1 query pattern (DB/API call inside loop) — batch or use asyncio.gather
  • Pydantic model missing ConfigDict(extra="forbid") — add it
  • get_x() method that is a simple property — convert to @property