Merge pull request #7050 from DDSRem-Dev/codex-comment-migration

docs: 统一全项目中文注释和结构化契约说明
This commit is contained in:
DDSRem
2026-10-17 19:26:29 +08:00
committed by GitHub
parent 3c7431b7da
commit 2de976f6b3
2345 changed files with 143990 additions and 61534 deletions

View File

@@ -1,4 +1,6 @@
"""插件市场候选事实与来源选择策略。"""
"""
插件市场候选事实与来源选择策略。
"""
from __future__ import annotations
@@ -25,7 +27,9 @@ LOCAL_PLUGIN_SOURCE_PREFIX = "local://"
def _build_public_local_source(plugin_id: str, package_generation: str) -> str:
"""生成不携带宿主路径的本地候选标识。"""
"""
生成不携带宿主路径的本地候选标识。
"""
source = f"{LOCAL_PLUGIN_SOURCE_PREFIX}{quote(plugin_id, safe='')}"
if package_generation != "v1":
source += f"?version={quote(package_generation, safe='')}"
@@ -33,29 +37,53 @@ def _build_public_local_source(plugin_id: str, package_generation: str) -> str:
class MarketReadStatus(StrEnum):
"""一次市场索引读取的最终状态。"""
"""
一次市场索引读取的最终状态。
"""
# 索引读取成功并存在,可返回空候选集合
PRESENT = "present"
# 已确认该市场没有请求代际的索引
ABSENT = "absent"
# 索引读取失败,不能当作索引不存在
FAILED = "failed"
class PluginSelectionStatus(StrEnum):
"""插件候选选择的可观察结果。"""
"""
插件候选选择的可观察结果。
"""
# 已选定唯一符合来源策略的候选
SELECTED = "selected"
# 没有符合条件的可用候选
UNAVAILABLE = "unavailable"
# 多个来源存在歧义或违反既有来源绑定
CONFLICT = "conflict"
# 市场或本地读取不完整,无法安全选择
INCOMPLETE = "incomplete"
class PluginSourceSelectionError(RuntimeError):
"""插件来源选择的策略错误。"""
"""
插件来源选择的策略错误。
"""
@dataclass(frozen=True, slots=True)
class PluginMarketCandidate:
"""一个在线市场条目的原始候选事实。"""
"""
一个在线市场条目的原始候选事实。
:param plugin_id: 物理插件标识,不使用分身实例标识
:param source_key: 经规范化的在线仓库身份键,格式为 github:所有者/仓库
:param source_type: 可信在线来源类型,区分官方与第三方
:param repo_url: 插件候选所在仓库的访问地址
:param package_generation: 插件包代际目录,例如 v1、v2 或 v3
:param plugin_version: 插件声明的业务版本;未提供时为 None
:param dto: 市场或本地扫描得到的原始元数据;未提供时为 None
:ivar normalized_plugin_id: 按小写规范化的物理插件身份键,由初始化自动计算,不接受构造参数
"""
plugin_id: str
source_key: str
@@ -67,7 +95,9 @@ class PluginMarketCandidate:
normalized_plugin_id: str = field(init=False)
def __post_init__(self) -> None:
"""校验候选身份,并把外部来源键归一为持久化合同使用的形式。"""
"""
校验候选身份,并把外部来源键归一为持久化合同使用的形式。
"""
normalized_id = normalize_physical_plugin_id(self.plugin_id)
source_type = _coerce_online_source_type(self.source_type)
source_key = validate_online_source_key(self.source_key)
@@ -85,11 +115,15 @@ class PluginMarketCandidate:
@property
def payload_source_type(self) -> PluginPayloadSourceType:
"""返回用于载荷审计的在线来源类型。"""
"""
返回用于载荷审计的在线来源类型。
"""
return PluginPayloadSourceType(self.source_type.value)
def public_dict(self) -> dict[str, Any]:
"""生成不携带原始元数据的公共候选投影。"""
"""
生成不携带原始元数据的公共候选投影。
"""
return {
"plugin_id": self.plugin_id,
"source_key": self.source_key,
@@ -102,7 +136,16 @@ class PluginMarketCandidate:
@dataclass(frozen=True, slots=True)
class PluginLocalCandidate:
"""一个本地插件载荷候选,与在线来源身份保持独立。"""
"""
一个本地插件载荷候选,与在线来源身份保持独立。
:param plugin_id: 物理插件标识,不使用分身实例标识
:param repo_url: 本地载荷仓库引用,仅在宿主内部使用,不直接对外公开
:param package_generation: 插件包代际目录,例如 v1、v2 或 v3
:param plugin_version: 插件声明的业务版本;未提供时为 None
:param dto: 市场或本地扫描得到的原始元数据;未提供时为 None
:ivar normalized_plugin_id: 按小写规范化的物理插件身份键,由初始化自动计算,不接受构造参数
"""
plugin_id: str
repo_url: str
@@ -112,7 +155,9 @@ class PluginLocalCandidate:
normalized_plugin_id: str = field(init=False)
def __post_init__(self) -> None:
"""校验本地载荷的插件与版本事实。"""
"""
校验本地载荷的插件与版本事实。
"""
normalized_id = normalize_physical_plugin_id(self.plugin_id)
repo_url = _normalize_repo_url(self.repo_url)
package_generation = normalize_package_generation(self.package_generation)
@@ -124,21 +169,29 @@ class PluginLocalCandidate:
@property
def payload_source_type(self) -> PluginPayloadSourceType:
"""返回本地载荷类型,不把本地路径伪装成在线来源。"""
"""
返回本地载荷类型,不把本地路径伪装成在线来源。
"""
return PluginPayloadSourceType.LOCAL
@property
def source_type(self) -> PluginPayloadSourceType:
"""返回独立的本地载荷类型,不伪造在线可信来源。"""
"""
返回独立的本地载荷类型,不伪造在线可信来源。
"""
return PluginPayloadSourceType.LOCAL
@property
def source_key(self) -> None:
"""本地载荷没有可绑定的在线来源键。"""
"""
本地载荷没有可绑定的在线来源键。
"""
return None
def public_dict(self) -> dict[str, Any]:
"""生成不包含本地仓库路径的公共候选投影。"""
"""
生成不包含本地仓库路径的公共候选投影。
"""
public_repo_url = _build_public_local_source(
self.plugin_id,
self.package_generation,
@@ -154,7 +207,15 @@ class PluginLocalCandidate:
@dataclass(frozen=True, slots=True)
class MarketRead:
"""记录一个配置市场的读取状态及其全部在线候选。"""
"""
记录一个配置市场的读取状态及其全部在线候选。
:param market: 本次读取的配置市场地址
:param status: 当前市场与包代际索引的读取状态,区分存在、不存在和失败
:param candidates: 本次读取获得的插件候选集合
:param error: 读取失败的可读原因;无错误时为 None
:param package_generation: 插件包代际目录,例如 v1、v2 或 v3
"""
market: str
status: MarketReadStatus
@@ -163,7 +224,9 @@ class MarketRead:
package_generation: str = "v1"
def __post_init__(self) -> None:
"""拒绝把失败读取伪装成空成功结果。"""
"""
拒绝把失败读取伪装成空成功结果。
"""
market = _normalize_market(self.market)
status = MarketReadStatus(self.status)
candidates = tuple(self.candidates)
@@ -194,7 +257,9 @@ class MarketRead:
*,
package_generation: str = "v1",
) -> "MarketRead":
"""构造存在的索引读取;真实空索引可以没有候选。"""
"""
构造存在的索引读取;真实空索引可以没有候选。
"""
return cls(
market=market,
status=MarketReadStatus.PRESENT,
@@ -209,7 +274,9 @@ class MarketRead:
*,
package_generation: str = "v1",
) -> "MarketRead":
"""构造已确认不存在的代际索引。"""
"""
构造已确认不存在的代际索引。
"""
return cls(
market=market,
status=MarketReadStatus.ABSENT,
@@ -224,7 +291,9 @@ class MarketRead:
*,
package_generation: str = "v1",
) -> "MarketRead":
"""构造失败读取,并保留可诊断但不用于选择的错误说明。"""
"""
构造失败读取,并保留可诊断但不用于选择的错误说明。
"""
return cls(
market=market,
status=MarketReadStatus.FAILED,
@@ -234,16 +303,22 @@ class MarketRead:
@property
def succeeded(self) -> bool:
"""判断该索引是否得到存在或不存在的确定结论。"""
"""
判断该索引是否得到存在或不存在的确定结论。
"""
return self.status is not MarketReadStatus.FAILED
@property
def present_index(self) -> bool:
"""判断该代际索引是否真实存在。"""
"""
判断该代际索引是否真实存在。
"""
return self.status is MarketReadStatus.PRESENT
def public_dict(self) -> dict[str, Any]:
"""生成市场读取的脱敏投影,保留状态、代际和候选事实。"""
"""
生成市场读取的脱敏投影,保留状态、代际和候选事实。
"""
return {
"market": self.market,
"package_generation": self.package_generation,
@@ -254,23 +329,36 @@ class MarketRead:
class LocalCandidateReadStatus(StrEnum):
"""一次本地插件仓库扫描的可观察终态。"""
"""
一次本地插件仓库扫描的可观察终态。
"""
# 本地扫描成功并存在仓库,可返回空候选集合
PRESENT = "present"
# 已确认不存在本地插件仓库
ABSENT = "absent"
# 本地扫描失败,候选完整性无法保证
FAILED = "failed"
@dataclass(frozen=True, slots=True)
class LocalCandidateRead:
"""记录本地候选扫描状态,避免扫描失败伪装成空仓库。"""
"""
记录本地候选扫描状态,避免扫描失败伪装成空仓库。
:param status: 本地仓库扫描结果,区分存在、不存在和失败
:param candidates: 本次读取获得的插件候选集合
:param error: 读取失败的可读原因;无错误时为 None
"""
status: LocalCandidateReadStatus
candidates: tuple[PluginLocalCandidate, ...] = ()
error: str | None = None
def __post_init__(self) -> None:
"""保证本地扫描状态、候选和错误说明相互一致。"""
"""
保证本地扫描状态、候选和错误说明相互一致。
"""
status = LocalCandidateReadStatus(self.status)
candidates = tuple(self.candidates)
if any(not isinstance(candidate, PluginLocalCandidate) for candidate in candidates):
@@ -294,7 +382,9 @@ class LocalCandidateRead:
cls,
candidates: Iterable[PluginLocalCandidate] = (),
) -> "LocalCandidateRead":
"""构造扫描成功的本地候选快照,空结果仍表示扫描成功。"""
"""
构造扫描成功的本地候选快照,空结果仍表示扫描成功。
"""
return cls(
status=LocalCandidateReadStatus.PRESENT,
candidates=tuple(candidates),
@@ -302,16 +392,22 @@ class LocalCandidateRead:
@classmethod
def absent(cls) -> "LocalCandidateRead":
"""构造没有配置本地仓库的结果。"""
"""
构造没有配置本地仓库的结果。
"""
return cls(status=LocalCandidateReadStatus.ABSENT)
@classmethod
def failure(cls, error: str) -> "LocalCandidateRead":
"""构造无法完成本地扫描的结果。"""
"""
构造无法完成本地扫描的结果。
"""
return cls(status=LocalCandidateReadStatus.FAILED, error=error)
def public_dict(self) -> dict[str, Any]:
"""生成不泄漏本地路径的扫描投影。"""
"""
生成不泄漏本地路径的扫描投影。
"""
return {
"status": self.status.value,
"error": self.error,
@@ -321,7 +417,15 @@ class LocalCandidateRead:
@dataclass(frozen=True, slots=True)
class CandidateInventory:
"""一次短生命周期市场快照,保留配置市场状态和全部候选。"""
"""
一次短生命周期市场快照,保留配置市场状态和全部候选。
:param market_reads: 各配置市场与包代际的读取事实
:param local_candidates: 兼容入口提供的本地候选集合
:param expected_markets: 必须完成读取的市场集合;None 从读取事实推导
:param expected_generations: 必须完成读取的包代际集合;与 expected_markets 同时为 None 时只要求已有读取全部成功
:param local_read: 本地扫描的明确结果;None 兼容使用 local_candidates
"""
market_reads: tuple[MarketRead, ...]
local_candidates: tuple[PluginLocalCandidate, ...] = ()
@@ -330,7 +434,9 @@ class CandidateInventory:
local_read: LocalCandidateRead | None = None
def __post_init__(self) -> None:
"""冻结快照输入,避免后续市场刷新改变选择依据。"""
"""
冻结快照输入,避免后续市场刷新改变选择依据。
"""
market_reads = tuple(self.market_reads)
local_candidates = tuple(self.local_candidates)
expected_markets = (
@@ -374,18 +480,24 @@ class CandidateInventory:
@property
def configured_markets(self) -> tuple[str, ...]:
"""按配置顺序返回本轮预期读取的市场。"""
"""
按配置顺序返回本轮预期读取的市场。
"""
if self.expected_markets is not None:
return self.expected_markets
return tuple(dict.fromkeys(read.market for read in self.market_reads))
def reads_for(self, market: str) -> tuple[MarketRead, ...]:
"""返回一个市场的全部代际读取事实。"""
"""
返回一个市场的全部代际读取事实。
"""
normalized_market = _normalize_market(market)
return tuple(read for read in self.market_reads if read.market == normalized_market)
def read_for(self, market: str, package_generation: str) -> MarketRead | None:
"""返回一个市场和代际的读取事实。"""
"""
返回一个市场和代际的读取事实。
"""
normalized_generation = normalize_package_generation(package_generation)
return next(
(
@@ -398,7 +510,9 @@ class CandidateInventory:
@property
def complete(self) -> bool:
"""只有预期市场与代际均可证明已成功读取时才算完整。"""
"""
只有预期市场与代际均可证明已成功读取时才算完整。
"""
if not self.market_reads or not all(read.succeeded for read in self.market_reads):
return False
expected_markets = self.expected_markets
@@ -417,7 +531,9 @@ class CandidateInventory:
@property
def can_use_for_tofu(self) -> bool:
"""判断快照是否足以证明唯一第三方来源。"""
"""
判断快照是否足以证明唯一第三方来源。
"""
local_read = self.local_read
return (
self.complete
@@ -427,7 +543,9 @@ class CandidateInventory:
@property
def online_candidates(self) -> tuple[PluginMarketCandidate, ...]:
"""按配置市场顺序返回全部在线候选,不按 ID 或版本去重。"""
"""
按配置市场顺序返回全部在线候选,不按 ID 或版本去重。
"""
return tuple(
candidate
for read in self.market_reads
@@ -436,7 +554,9 @@ class CandidateInventory:
)
def candidates_for(self, plugin_id: str) -> tuple[PluginMarketCandidate, ...]:
"""读取一个插件 ID 的全部在线候选。"""
"""
读取一个插件 ID 的全部在线候选。
"""
normalized_id = normalize_physical_plugin_id(plugin_id)
return tuple(
candidate
@@ -445,7 +565,9 @@ class CandidateInventory:
)
def local_candidates_for(self, plugin_id: str) -> tuple[PluginLocalCandidate, ...]:
"""读取一个插件 ID 的全部本地候选。"""
"""
读取一个插件 ID 的全部本地候选。
"""
normalized_id = normalize_physical_plugin_id(plugin_id)
return tuple(
candidate
@@ -454,7 +576,9 @@ class CandidateInventory:
)
def public_dict(self) -> dict[str, Any]:
"""生成完整库存的脱敏投影,不泄漏本地路径或原始 DTO。"""
"""
生成完整库存的脱敏投影,不泄漏本地路径或原始 DTO。
"""
local_read = self.local_read
if local_read is None:
raise RuntimeError("候选清单缺少本地读取终态")
@@ -468,7 +592,14 @@ class CandidateInventory:
@dataclass(frozen=True, slots=True)
class PluginSelection:
"""候选选择结果,冲突和不完整状态均不降级为静默空值。"""
"""
候选选择结果,冲突和不完整状态均不降级为静默空值。
:param status: 候选选择状态,区分选定、不可用、冲突和信息不完整
:param candidate: 唯一被选定的候选;未选定时为 None
:param conflict_source_keys: 产生同名来源冲突的仓库键
:param reason: 未能选定候选的可读原因,默认空字符串
"""
status: PluginSelectionStatus
candidate: PluginMarketCandidate | PluginLocalCandidate | None = None
@@ -476,7 +607,9 @@ class PluginSelection:
reason: str = ""
def __post_init__(self) -> None:
"""保证选择状态与载荷及冲突信息相互一致。"""
"""
保证选择状态与载荷及冲突信息相互一致。
"""
status = PluginSelectionStatus(self.status)
conflict_source_keys = tuple(sorted(set(self.conflict_source_keys)))
if status is PluginSelectionStatus.SELECTED and self.candidate is None:
@@ -490,11 +623,15 @@ class PluginSelection:
@property
def selected(self) -> bool:
"""判断是否已经选择出一个载荷候选。"""
"""
判断是否已经选择出一个载荷候选。
"""
return self.status is PluginSelectionStatus.SELECTED
def public_dict(self) -> dict[str, Any]:
"""生成安全的选择结果投影,不透传本地路径或原始 DTO。"""
"""
生成安全的选择结果投影,不透传本地路径或原始 DTO。
"""
result: dict[str, Any] = {
"status": self.status.value,
"reason": self.reason,
@@ -510,7 +647,9 @@ Candidate: TypeAlias = PluginMarketCandidate | PluginLocalCandidate
def normalize_package_generation(package_generation: str) -> str:
"""校验并归一插件包代际。"""
"""
校验并归一插件包代际。
"""
value = str(package_generation).strip().lower()
if value not in PLUGIN_GENERATIONS:
raise ValueError("插件包代际必须为 v1、v2 或 v3")
@@ -525,7 +664,9 @@ def _select_local_candidate(
generation_order: tuple[str, ...],
local_candidates: Iterable[PluginLocalCandidate] | None,
) -> PluginSelection | None:
"""优先选择本地载荷;读取失败时阻止自动降级到在线来源。"""
"""
优先选择本地载荷;读取失败时阻止自动降级到在线来源。
"""
local = (
tuple(local_candidates)
if local_candidates is not None
@@ -581,7 +722,7 @@ def select_plugin_candidate(
:param local_candidates: 可选的本地载荷候选;已有在线绑定时参与代际和版本比较
:param requested_source_key: 调用方提供的规范在线来源;非显式调用不能绕过本地载荷
:param explicit_source: 本次调用是否代表管理员明确选源
:param allow_source_change: 是否是带 revision 的显式换源命令
:param allow_source_change: 是否是带版本号的显式换源命令
:return: 带明确冲突或不完整状态的选择结果
"""
normalized_id = normalize_physical_plugin_id(plugin_id)
@@ -712,7 +853,9 @@ def _select_bound_source_candidate(
identity: PluginIdentity | None,
generation_order: tuple[str, ...],
) -> PluginSelection:
"""只在已绑定仓库范围内选取在线候选,并与可用本地载荷协调。"""
"""
只在已绑定仓库范围内选取在线候选,并与可用本地载荷协调。
"""
if identity is None:
raise PluginSourceSelectionError("已绑定来源选择缺少插件身份")
source_type, source_key = allowed_source
@@ -757,7 +900,9 @@ def _select_bound_or_local_candidate(
identity: PluginIdentity,
generation_order: tuple[str, ...],
) -> PluginSelection:
"""在已绑定在线候选和本地候选之间选择代际、版本更高的载荷。"""
"""
在已绑定在线候选和本地候选之间选择代际、版本更高的载荷。
"""
if (
local_selection is None
or local_selection.status is not PluginSelectionStatus.SELECTED
@@ -806,7 +951,9 @@ def list_effective_online_candidates(
plugin_id: str,
generations: Sequence[str],
) -> tuple[PluginMarketCandidate, ...]:
"""按来源列出当前运行代际实际可安装的最高版本候选,官方来源始终置顶。"""
"""
按来源列出当前运行代际实际可安装的最高版本候选,官方来源始终置顶。
"""
generation_order = _normalize_generation_order(generations)
grouped: dict[
tuple[TrustedPluginSourceType, str],
@@ -836,7 +983,9 @@ def get_effective_local_candidate(
plugin_id: str,
generations: Sequence[str],
) -> PluginLocalCandidate | None:
"""返回本地插件目录中当前运行代际优先级最高的安全候选。"""
"""
返回本地插件目录中当前运行代际优先级最高的安全候选。
"""
candidate = _select_best(
inventory.local_candidates_for(plugin_id),
_normalize_generation_order(generations),
@@ -845,7 +994,9 @@ def get_effective_local_candidate(
def _coerce_online_source_type(source_type: TrustedPluginSourceType) -> TrustedPluginSourceType:
"""把外部字符串来源类型转换为可信在线来源枚举。"""
"""
把外部字符串来源类型转换为可信在线来源枚举。
"""
value = TrustedPluginSourceType(source_type)
if value is TrustedPluginSourceType.UNKNOWN:
raise ValueError("未知来源不能作为在线市场候选")
@@ -853,7 +1004,9 @@ def _coerce_online_source_type(source_type: TrustedPluginSourceType) -> TrustedP
def _normalize_market(market: str) -> str:
"""校验市场标识,保留其作为本轮快照的显示值。"""
"""
校验市场标识,保留其作为本轮快照的显示值。
"""
value = str(market).strip()
if not value:
raise ValueError("插件市场标识不能为空")
@@ -861,7 +1014,9 @@ def _normalize_market(market: str) -> str:
def _normalize_repo_url(repo_url: str) -> str:
"""保留仓库地址作为安装事实,但移除无意义的外围空白。"""
"""
保留仓库地址作为安装事实,但移除无意义的外围空白。
"""
value = str(repo_url).strip()
if not value:
raise ValueError("插件仓库地址不能为空")
@@ -869,7 +1024,9 @@ def _normalize_repo_url(repo_url: str) -> str:
def _normalize_plugin_version(plugin_version: str | None) -> str | None:
"""标准化可选插件声明版本,并保持缺失版本可观察。"""
"""
标准化可选插件声明版本,并保持缺失版本可观察。
"""
if plugin_version is None:
return None
value = str(plugin_version).strip()
@@ -881,7 +1038,9 @@ def _normalize_plugin_version(plugin_version: str | None) -> str | None:
def _normalize_generation_order(generations: Sequence[str]) -> tuple[str, ...]:
"""校验调用方提供的代际优先序,并拒绝重复项。"""
"""
校验调用方提供的代际优先序,并拒绝重复项。
"""
normalized = tuple(normalize_package_generation(generation) for generation in generations)
if not normalized:
raise ValueError("至少需要一个当前运行代际")
@@ -894,7 +1053,9 @@ def _allowed_source(
identity: PluginIdentity | None,
normalized_plugin_id: str,
) -> tuple[TrustedPluginSourceType, str] | None:
"""从已安装身份读取不可变的允许在线来源。"""
"""
从已安装身份读取不可变的允许在线来源。
"""
if identity is None:
return None
if identity.normalized_plugin_id != normalized_plugin_id:
@@ -910,7 +1071,9 @@ def _select_best(
candidates: Sequence[Candidate],
generation_order: Sequence[str],
) -> Candidate | None:
"""在已完成来源过滤后按代际和同源版本选择最高候选。"""
"""
在已完成来源过滤后按代际和同源版本选择最高候选。
"""
for generation in generation_order:
generation_candidates = tuple(
candidate
@@ -923,7 +1086,9 @@ def _select_best(
def _select_highest_version(candidates: Sequence[Candidate]) -> Candidate:
"""使用宿主既有版本比较语义选择同源最高版本,平级保留先读候选。"""
"""
使用宿主既有版本比较语义选择同源最高版本,平级保留先读候选。
"""
selected = candidates[0]
for candidate in candidates[1:]:
selected_version = selected.plugin_version or "0"