73 lines
5.6 KiB
Markdown
73 lines
5.6 KiB
Markdown
# FreeCAD Web Python API 源符号追踪路线
|
||
|
||
> 2026-09-06:本文件保留为源码追踪与后置审计参考。当前实现主线已切换为
|
||
> [`WEB_IMPLEMENTATION_FIRST_STRATEGY.md`](WEB_IMPLEMENTATION_FIRST_STRATEGY.md) 的
|
||
> 用户功能链优先模式;不得再把 13,385/13,386 个符号逐条 gate 当作功能移植队列。
|
||
|
||
## 目标与边界
|
||
|
||
FreeCAD 当前 `.py/.pyi` 源码 inventory 有 13,385 条 Python API 记录(class 2,053、function 2,380、method 8,952,覆盖 29 个模块);manifest 另含一个来自 C++ binding 的 `Part.makeBox`,所以追踪总数为 13,386。该数字不是用户功能数。后置审计可让每条记录最终获得 `exposed`、`restricted`、`nonportable` 或 `not_implemented` 结论,但不能阻断当前功能实现。
|
||
|
||
这条路线不为每个 API 手写一个 React facade。inventory 负责逐条可追溯性,生成 manifest 负责稳定身份与分类,少量运行时 adapter family 负责实际转换和调度。
|
||
|
||
## 去重与分层
|
||
|
||
`tools/generate_python_api_manifest.py` 从 `docs/format-api-inventory.json` 生成 `docs/p6/python-api-manifest.json`。稳定身份是 `module + kind + fully-qualified name`;源码路径和行号只作证据,不能导致重复绑定。重载或同一操作的差异保留在签名证据中,统一进入同一个家族 adapter。
|
||
|
||
当前 manifest 将所有记录压缩到有限的可复用家族:`geometry-value`、`pure-function`、`property`、`document-graph`、`lifecycle-command`、`serialization`、`view-resource`、`gui-external` 和 `generic-object`。家族只是生成/测试路由,不是完成状态;每条记录初始 `disposition=planned`,不得据此宣称已移植。
|
||
|
||
运行时层级固定为:
|
||
|
||
| 层级 | 处理内容 | 复用单元 |
|
||
|---|---|---|
|
||
| Tier 0 substrate | Python/WASM 值、序列、异常、Document handle、取消和资源生命周期 | 一个转换与错误 ABI |
|
||
| Tier 1 readonly | 类注册、常量、getter、资源和只读查询 | 生成 schema + 只读 dispatch |
|
||
| Tier 2 pure | 无文档副作用的函数、几何/值计算 | 类型转换器 + 纯函数 dispatch |
|
||
| Tier 3 stateful | Document、Property、链接、重算、事务、序列化和命令 | Document actor + 事务 adapter |
|
||
| Tier 4 restricted | GUI/PySide/Pivy、桌面动态模块、外部进程或浏览器禁止的 I/O | capability policy;`restricted`/`nonportable`/`not_implemented` |
|
||
|
||
## 生成式流水线
|
||
|
||
```text
|
||
源码 inventory
|
||
-> normalize (stable id, name/kind/module)
|
||
-> dedupe (exact key; retain evidence)
|
||
-> family/tier classification
|
||
-> generated manifest + TypeScript schema + dispatch tables
|
||
-> one Python/WASM Worker batch request
|
||
-> native execution + typed result/error envelope
|
||
-> differential/replay fixtures
|
||
-> disposition gate and release ledger
|
||
```
|
||
|
||
前端每次请求使用统一 envelope:`requestId`、`apiId[]`、`args`、`documentId`、`capabilities`、`signal`。同一 Worker 批量执行一组调用,共享一次解释器/原生上下文;禁止“一 API 一页面”或“一 API 一 Worker”。批量边界按事务和取消点切分,错误以 `apiId` 粒度返回,后续调用不会吞掉前一调用的异常。
|
||
|
||
生成物必须包含:
|
||
|
||
- canonical API manifest(逐条 id、家族、层级、源码证据和 disposition);
|
||
- TypeScript 参数/返回值 schema、权限表和按家族分组的 dispatch;
|
||
- C/C++/Python-WASM trampoline 的统一值转换、异常、取消和资源释放 ABI;
|
||
- 每个家族一组参数边界、错误语义、重放和内存释放测试;不是每个符号一套手工测试代码。
|
||
|
||
## 执行顺序
|
||
|
||
1. **冻结输入**:记录 inventory SHA-256、FreeCAD revision、manifest schema version;输入变更就重新生成,禁止编辑生成 JSON。
|
||
2. **完成 substrate 和 Document actor**:先让 Tier 0/3 的 handle、属性、事务、重算、Undo/Redo、恢复可批量调用,这是最多 API 的共享依赖。
|
||
3. **生成 Tier 1/2**:按模块和 adapter family 生成 dispatch,优先覆盖只读与纯函数;每个生成批次附 source path/line 证据。
|
||
4. **实现权限策略**:Tier 4 在 manifest 中逐条给出 `restricted`、`nonportable` 或 `not_implemented` 原因;不能用静态 JS 值冒充执行。
|
||
5. **差分与回放**:同一 fixture 在 desktop Python 与 Web Python/WASM 执行,比较类型、数值容差、文档 diff、异常类别、取消点和资源计数;失败保留最小重放包。
|
||
6. **发布门槛**:只有 13,385 条记录全部离开 `planned`,且生成 hash、权限审计、Chrome worker 回放和内存释放 gate 通过,FPA-F 才能关闭。
|
||
|
||
## 不重复的工程规则
|
||
|
||
- 不复制模块级 facade 逻辑;facade 只负责 envelope、批处理、取消和错误映射。
|
||
- 不把 `path/line` 当 API 身份;同名重载必须进入同一家族并携带签名证据。
|
||
- 不为每条 API 单独启动 Python;一个 Worker/actor 承载批次和事务边界。
|
||
- 不为每个 API 写重复测试;测试按转换器、家族、权限策略和代表性签名参数化生成。
|
||
- 缓存键必须包含 `sourceRevision + inventorySha256 + manifestSha256 + runtimeAbi + schemaVersion`,防止旧 binding 混入新源码。
|
||
- 任何未分类、无签名或无结果证据的记录保持 `planned`,直接阻止完整对标出口。
|
||
|
||
## 当前证据与下一步
|
||
|
||
当前生成器已经核对 13,385 条记录的精确键重复数,并写出逐条 manifest;这完成了 FPA-A 的 API 路线冻结,不代表 FPA-F 已完成。FPA-B/C 先提供 React 核心壳层、Document actor 和事务合同;随后 FPA-F 按 manifest 的 Tier 0 -> 1/2 -> 3/4 顺序实现,并以家族级差分回放收口。
|