# 08 — Comments and Documentation Style ## ⚠️ Mandatory Gate All **public classes**, **public methods**, and **public functions** in this project must have Chinese docstrings. Code submitted without compliant docstrings on public interfaces will be **rejected at review**. No exceptions. "Public" means anything not prefixed with `_`. This includes all methods on `ChainBase` subclasses, `_ModuleBase` subclasses, Pydantic schema classes, and endpoint functions. --- ## Docstring Format ### Single-line (for simple, obvious descriptions) ```python def get_name() -> str: """获取模块名称""" return "Qbittorrent" ``` ### Multi-line (for methods with parameters, return values, or non-obvious behavior) ```python def download( self, context: Context, torrent: TorrentInfo, download_dir: Path, ) -> Optional[str]: """ 添加下载任务到下载器。 :param context: 当前媒体上下文,包含识别结果和种子选择信息 :param torrent: 要下载的种子信息 :param download_dir: 目标保存目录 :return: 成功时返回下载任务 ID,失败时返回 None """ ... ``` ### Class docstrings ```python class DownloadChain(ChainBase): """ 下载处理链,负责协调搜索结果的种子选择、下载器调度和下载后处理。 """ ``` --- ## Docstring Language Rule - **Default:** Chinese. - **Exception:** If the surrounding file is entirely and consistently in English, match the local style. - Do not mix languages within a single docstring. Pick one and stay consistent for the whole file. --- ## Inline Comments **Only add an inline or block comment when the WHY is non-obvious.** Good reasons to add a comment: - A hidden external constraint (e.g., "this API returns stale data for up to 60 seconds after update") - A subtle invariant the code must maintain - A workaround for a specific third-party bug - Call ordering or initialization requirements that are not apparent from the code - Compatibility reasons with a specific client version or protocol **Do not add a comment when:** - The code already explains itself through well-named identifiers - The comment would just restate what the code does in words - The logic is straightforward branching or assignment --- ## Correct Examples ```python # qBittorrent API 在添加种子后立即查询时可能返回空,需要短暂等待 time.sleep(0.5) result = self.client.get_torrent(hash_id) ``` ```python # 此处必须先检查 module 是否已初始化,否则多线程并发调用时 get_instances() 可能返回空列表 if not self._initialized: self.init_module() ``` --- ## Incorrect Examples ```python # 获取订阅列表 ← 这只是在重述代码,不需要 subscribes = SubscribeOper().list() # 如果 result 为 None 则返回 ← 无意义 if result is None: return None # change starts here ← 噪音,禁止 # fix: handle edge case ← 噪音,改成提交信息里写 ``` --- ## Comment Placement - Place block comments **above** the code they describe, not on the same line. - Use same-line end-of-line comments only for very short clarifications (e.g., unit of a constant). - For long explanations, prefer a block comment above the code rather than a multiline end-of-line comment. ```python # 优先使用已有的下载目录映射,避免重复计算路径 effective_dir = self._resolve_download_dir(torrent) or download_dir ``` --- ## Stale Comment Rule When modifying code, update or remove any comment that no longer accurately describes the implementation. A stale comment is worse than no comment — it actively misleads future readers. --- ## Prohibited Patterns | Pattern | Why | |---|---| | `# change starts here` / `# change ends here` | Editorial noise; belongs in git history, not source | | `# TODO` without context or assignee | Accepted only when the deferral is genuinely unavoidable and the reason is documented | | `# FIXME` left in submitted code | Fix it now or document exactly why it cannot be fixed | | `# this is important` | Every line of code is important; this adds nothing | | Commented-out dead code | Delete it; git history preserves it | | Docstrings in English on new public interfaces | Violation of the mandatory Chinese docstring gate | *Last Updated: 2026-05-25*