MEP 1 – MEP 目的和准则#

编号:

1

标题:

MEP 目的和准则

作者:

The MegEngine Open Source Team

状态:

草稿

类型:

流程

创建时间:

2021-06-09

备注

我们正在尝试以 PEP 1 内容为蓝本撰写、实施该提案,感谢 Python 软件基金会的探索。

什么是 MEP?#

MEP 是 MegEngine Enhancement Proposal 的缩写,意为“MegEngine 增强提案”。 每个 MEP 都应该是一份设计文档,负责为 MegEngine 社区提供信息参考,或描述 MegEngine 特性的发展历史。 在标准 MEP 中应提供关于某个特性的简明技术规范,并且介绍实现该特性的基本原理。

我们希望 MEP 能够成为 MegEngine 提出新的重大特性、收集社区对某个问题的意见以及记录已有设计决策的主要机制。 MEP 的作者负责在社区内建立广泛的共识,聆听并记录不同的意见。

当前 MEP 作为 MegEngine 官方文档的一部分,通过 Git 进行版本控制,支持通过 MEP 修订历史 查看历史版本。

所面向的受众#

MEP 的典型受众可分为以下几类:

  • MegEngine 的核心开发人员

  • 从社区选举产生的发展改革委员会

  • MegEngine 衍生库的开发人员

作为 MegEngine 文档的一部分,文档中的一些页面将引用 MEP 中的内容作为参考(尤其是开发者指南部分), 开发者指南中的内容也有可能发展成为对 MEP 的补充,甚至是新的 MEP.

备注

  • 我们经常会在 MEP 中提到 “MegEngine 发展改革委员会” (MegEngine Development and Reform Commission, 简称 MDRC), 或者 “MegEngine 发改委”、“委员会”。委员会成员的意见将最终决定某个 MEP 是被接受还是拒绝。

  • 我们也会在 MEP 中提到 “MegEngine 核心开发者”(MegEngine Core Developer, 简称 MCD)

  • MEP 编辑(Editor)也是 MEP 发展过程中不可或缺的一个角色。

警告

当前阶段,MegEngine 社区成员角色选举和分配机制尚未成熟, 请先尝试成为 MegEngine 开发者团体的一员,将来我们会提供额外专门的流程 MEP 以形成规范。

MEP 所用语言#

目前要求统一使用中文进行编写,根据用户和开发者的使用语言比例变化,这个决定将来可能会被替代。

MEP 类型#

MEP 可分为三种类型:

  • 标准追踪类型(Standards Track)。 此类 MEP 负责描述 MegEngine 中新特性的原理和实现, 也有可能负责在当前版本的 MegEngine 还未提供相应支持之前,描述一个互操作性标准。

  • 信息类型(Information)。 此类 MEP 负责描述与 MegEngine 有关的设计讨论,或为 MegEngine 社区提供信息或指导。 信息类型的 MEP 不会提出一个新特性,因此用户和开发人员可自行选择忽略还是遵循里面的建议。

  • 流程类型(Process)。 此类 MEP 负责描述与 MegEngine 相关的各项流程,或如何对流程(或者里面的事件)进行更改。 流程类型的 MEP 与标准追踪类型有些类似,但又不局限于 MegEngine 本身; 此类 MEP 中可能提出了一个并非针对 MegEngine 源代码库的实现;通常这需要社区达成共识; 与信息类型的 MEP 不同,它们不仅仅是一种建议,社区开发者通常不能随意忽略其中的内容。 样例包括决策流程的步骤、指导与变更,以及开发环境和工具的变更。任何 meta-MEP 也被看作是流程类型 MEP.

MEP 工作流#

警告

单个的 MEP 中需包含有关键的提案或提供新的改进性的想法。

  • 小规模的增强或补丁通常不需要 MEP, 可以通过 Issues 或 Pull Request 来进行追踪。

  • 一个 MEP 应当关注某一个具体的点;如果 MEP 显得过于分散或宽泛,MEP 编辑将保留拒绝的权利。

  • 如果你的 MEP 由于过于宽泛而被拒绝,请考虑将其拆分为多个更加专注的 MEPs.

从一个小的想法开始#

MEP 的整个流程始于与 MegEngine 有关的灵光一闪。

但一种常见的情况是:用户而非开发者在 GitHub Issue 中提出了某特性需求(Feature Requirement)且为增强(Enhancement)类型, 如果仅描述了需要实现的效果,而实现方案、基本原理、设计规格内容完全由他人补充,则用户不应该纳入 MEP 的作者列表中。 MEP 作者有义务提供更多的细节,而不仅仅是最终的目标。

每个 MEP 必须有一个负责人(即主要作者) —— 要求使用本提案中提到的风格和格式进行 MEP 的编写,引导用户在社区中进行讨论, 并试图围绕这个想法建立社区共识。MEP 的负责人首先要做的是:确定自己的想法是否可形成 MEP. 如果不是很确定,最好的方式是在 MegEngine 官方论坛相关的板块(或任何正式渠道)提前进行交流。 在编写 MEP 之前要求在社区提前交流自己的想法,好处是这可以潜在地节省彼此的时间:

  • 避免将过多时间花在那些 肯定会被拒绝的 事情上,因为它先前已经被讨论过了,但这些相关内容并不一定能在互联网上找到。 所以建议首先向 MegEngine 社区询问你的某个想法是否为原创,这将有所帮助。

  • 一个想法可能对作者来说听起来不错,但这并不意味着它适用于大多数使用 MegEngine 的用户和开发者。 你需要确保该想法适用于整个 MegEngine 社区,造福群众,而不仅仅是一家之言。

一旦作者打算向 MegEngine 社区询问某个想法是否有机会被接受,就可以开始着手准备一份 MEP 草案。 作者能借写作去梳理、拓展和反思自己的想法,也能确保投入足够的时间使得 MEP 的格式正确、初始内容质量较高。

警告

MEP 作者有责任在提交 MEP 以供审查之前收集社区对 MEP 的反馈。

如何提交 MEP#

确定需要提交一份 MEP 草案后,后续的流程会根据 MEP 的作者是否属于 MegEngine 核心开发者而有所不同。

备注

  • 如果 MEP 的作者本人并不属于 MegEngine 核心开发者,则需要为自己的想法寻找一位担保人。 理想情况下,需要确认一名核心开发者作为 MEP 担保人,但也可以在委员会的批准下选择非核心开发者作为担保人。 担保人的职责是为 MEP 作者提供后续指导,帮助他/她(们)完成 MEP 流程的后勤工作(有点类似于导师),担保人可作为 MEP 的合作者。 每个 MEP 的担保人信息(如果有)应该记录在 MEP 文件头部的 “:担保人:” 字段。

  • 如果 MEP 的作者本人即 MegEngine 的核心开发者,则无需寻找担保人。

一旦作者认为 MEP 已经准备好提交,则应该通过 GitHub Pull Request 将提案作为 MEP 草案提交。 草案必须按如下所述以 MEP 风格编写,否则将立即无法通过审核(这个过程中编辑可能会更正一些存在的小错误)。

标准的 MEP 草案提交流程是:

  1. 作为 MEP 的作者,分叉(Fork) Documentation 存储库, 在 source/development/meps/ 目录中创建一个名为 mep-9999.rst 的文件, 其中包含你的新 MEP, 并使用 “9999” 作为草案的编号;

  2. 在 “:类型:” 字段中,根据实际情况填入 “标准追踪”、“信息” 或 “流程”,并在 “:状态:” 字段中填入 “草稿”。 有关的完整信息,请参考 MEP 头部内容

  3. 推送(Push)到你的 GitHub 分叉并提交一个拉取请求(Pull Request).

  4. MEP 编辑会审查你的 PR 结构、格式和其它类型的错误。我们要求统一提供 reST 格式的 MEP, 参考 Sphinx reStructuredText 语法入门 。 批准 MEP 的标准是:

    • 听起来很完整,想法必须具有技术意义,但编辑并不考虑它是否有可能被接受。

    • 标题准确精炼地描述了内容。

    • MEP 的语言(拼写、语法、句子结构等)和代码风格应该正确且一致。

    如果 MEP 尚未准备好接受批准,编辑会将其发回给作者进行修订,并附有具体说明。

  5. 一旦获得批准,编辑将为你的 MEP 分配一个编号。

备注

一旦审核过程结束且被 MEP 的编辑批准(批准并不意味你的 MEP 已经被接受),所有你的 Pull Request 中的提交将被合并且推送到主分支。 这意味着任何人都可以从 MegEngine 文档中看到你的 MEP 草案,并可以在其它地方的讨论中引用对应的 MEP 编号。

编辑不会无理拒绝 MEP 草案的发布。拒绝 MEP 的通常原因包括重复工作、技术上不健全、没有提供适当的动机或解决向后兼容性问题, 或者不符合 MegEngine 设计理念。在这个阶段也可以选择咨询发展改革委员会,委员会是相关内容是否能作为 MEP 草案发布的最终仲裁者。

警告

MEP 草案被编辑批准并不保证里面没有令人尴尬的错误,正确性是作者和审稿人的责任。

警告

具有 Documentation 库 git push 权限的开发人员可以通过创建和提交新的 MEP 并直接声明 MEP 编号, 如果执行上述操作,则执行人必须自己处理通常由 MEP 编辑处理的任务以确保初始版本符合提交 MEP 的预期标准。 我们更加推荐一切按部就班,即开发人员也应该通过 Pull Request 拉取请求来提交 MEP 内容。 但针对新版本中的适应性更改,如果 MEP 作者(或合作开发人员)具有 git push 权限,则可以直接对旧的 MEP 进行更新。

MEP 流程状态#

作者完成 MEP 后,他/她(们)可能会要求 MEP 编辑对风格和一致性进行审查,但最终的草案必须向核心开发者请求内容审查。 为了在特定的情况下加快流程(例如某个 MEP 的更改显然对 MegEngine 有益并准备好被接受,但尚未正式提交审查时), 发展改革委员会也可以启动 MEP 审查,决定接受或拒绝,但需要事先通知 MEP 作者并让他/她(们)有机会进行完善和修改。

接受(或拒绝) MEP 的最终权力机构是委员会。但每当新的 MEP 出现时,任何认为自己有适当经验、 能够对该 MEP 做出最终决定的核心开发人员也可以提议担任该 MEP 的决策人,然后他/她(们)将有权接受(或拒绝)该 MEP. 承担此责任的个人可以随时向委员会寻求更多指导,并且还应考虑其他核心开发人员的建议和观点。

草稿(Draft)状态的 MEP 草案提交后,MEP 状态可能的路径如下:

MEP process flow diagram

如果没有志愿者挺身而出成为决策人,那么委员会将与具有相关专业知识的核心开发者接触,以尝试确定愿意担任该 MEP 决策的候选人。 如果找不到合适的候选人,那么 MEP 将被标记为推迟(Deferred)直到有人愿意开始进行相关决策。 已被任命的 MEP 决策人可以选择下台,或被委员会要求下台。在这种情况下,将按照与新 MEP 相同的方式任命新的 MEP 决策人。 如果 MEP 决策人被要求下台,这将推翻之前对 MEP 的任何接受或拒绝决定,并将恢复到草案状态。

要使 MEP 被接受(Accepted),它必须满足某些最低标准:

  • 它必须包含对增强特性的清晰完整的描述。

  • 增强必须意味着改进,而不是一些平凡的变化。

  • 实现方案必须是可靠的,阐明清楚了其基本原理和设计规格。

  • 最后,提案中的增强特性必须符合 MegEngine 的设计哲学。

接受(Accpeted)& 完成(Final)

一旦标准追踪类型但 MEP 被标记为接受,表明该特性是 MegEngine 所需要的, 则可以考虑进入 Git 协作流程 开始进行实现。 当参考实现完成,通过代码审查(Code Review)并合并到 MegEngine 源代码存储库中时,MEP 状态将更改为“完成”(Final)。

  • 一个 MEP 也有可能长期处于已被接受的状态,这通常是由于优先级不够高,或者核心开发人员者没有时间和精力去实现它们。

  • 已被接受的 MEP 允许存在来自不同开发者的多个竞争实现,但最终只会采纳其中一个作为最终实现。 其它没有被采纳的实现也会在 MEP 中被记录,用作后续可能的追踪。

生效(Active)

对于信息类和流程追踪类的 MEP, 其最终归宿应当是“生效”(Active)。

临时(Provisonal)

为了在承诺 API 的长期稳定性之前收集额外的反馈信息,MEP 也可以标记为“临时”(Provisnal),代表“Provisionally Accepted”, 表示该提案已被接受以包含在参考实现中,但需要额外的用户反馈才能将设计视为完成状态。 在可能的情况下,最好缩小提案的范围以避免出现“临时”状态。 与常规接受的 MEP 不同,即使在某个 MegEngine 版本中合并对应改动之后,临时接受的 MEP 仍可能被拒绝或撤回。

延期(Deferred)

当 MEP 没有取得任何进展时,MEP 作者或编辑可以为其分配“延期”(Deferred)状态。 一旦 MEP 被延期,MEP 编辑可以将其重新分配为草稿状态,等待作者进行后续的补充。

拒绝(Rejected)

MEP 也可以被“拒绝”(Rejected),即最终不被接受。

撤回(Withdawn)

“撤回”(Withdawn)意味着作者自己已经认为曾经提出的 MEP 实际上是一个坏主意, 或者已经认同了某个竞争提案是更好的选择。

警告

当 MEP 完成、拒绝或撤回时,需要进行相应的更新。除了更新状态字段之外, 至少应该添加与最终解决方案有关的链接(一个新的 MEP, 或者一个合并的 Pull Request)。

警告

MEP 也可以被不同的 MEP 取代,从而使原始版本过时。

MEP 维护#

通常,标准追踪 MEP 在达到完成状态后不再修改。一旦 MEP 完成,将成为正式的文档内容。 如果根据实践经验和用户反馈,对处于已接受或临时状态的标准追踪 MEP 进行更改, 则应在 MEP 中注明这些更改,以便 MEP 能够准确描述最终的实现。

信息和流程类型的 MEP 可能会随着时间的推移而更新,以反映开发实践和其他细节的变化。

MEP 参考模版#

如果一个标准追踪 MEP 达到了完成状态,其结构与下面提供的模版应当高度相似。

头部内容

包含有关 MEP 的元数据,具体细节请参考 MEP 头部内容

简介

是什么(What)。简短地描述当前 MEP 正在解决的技术问题。

动机

为什么(Why)。清楚地解释为什么现有的实现不足以解决问题。

基本原理

如何处理(How)。简单介绍解决技术问题的思路、原理和方法。

设计规范

即 Specification. 这在 MEP 的初始流程中是最重要的一部分,是对解决方案的最简展示。 通常需要介绍打算引入什么样的接口,执行逻辑如何,可以使用伪代码和图片来作为补充说明。 好的设计规范应该能保证:具有相似编程经验和背景的人能够参照着该规范进行具体的实现。 MEP 决策人可以通过设计规范判断出该提案是否可行,以及是否可被接受。

需要注意的是,设计规范不需要也不应该涉及到代码实现的细节。

向后兼容性

所有引入向后不兼容的 MEP 都必须描述这些不兼容部分及其严重性。 解释作者打算如何处理这些不兼容性。没有足够的向后兼容性论文的 MEP 提交可能会被彻底拒绝。

安全影响

如果存在与安全相关的问题,则应明确写出,以确保决策者了解这些问题。

示例

对于添加新功能或改变旧接口行为的 MEP,提供关于如何教新的和有经验的用户进行使用的说明。 通常这一部分可以被用来作为单元测试的参考,也可以被用于教程或用户指南。

参考实现

这一部分不需要事先提供,直到 MEP 变为接受状态。 但必须提供一个被 MegEngine 代码库合并的拉取请求或提交记录作为参考实现,MEP 才能被标记为“完成”状态。 如果存在着多个竞争实现,除了被合并的实现外,其它的实现也应该被列举在此处。

被拒绝的想法

在 MEP 的整个讨论中,将提出各种未被接受的想法。那些被拒绝的想法应该与拒绝的原因一起记录下来。 这既有助于记录 MEP 在完成之前背后的思考过程,也有助于防止人们在后续讨论中再次提出相同的被拒绝的想法。

未解决的问题

当 MEP 处于草案中时,可能会出现一些值得进一步讨论的想法。 应该记录这些想法,以便人们知道他/她(们)正在考虑但没有具体的解决方案。

致谢

如果任何人或机构对 MEP 的讨论和实现提供了实质性的帮助,需要表达感谢。

版权/许可

每个新的 MEP 都必须置于公共领域和 CC0-1.0-Universal 的双重许可之下。

每个 MEP 都需要在这里提供一个指向源文件的链接。

MEP 头部内容#

必须按以下顺序出现,标有 * 的标题是可选的,所有其他标题都是必需的。

  :编号: <MEP 编号>
  :标题: <MEP 标题>
  :作者: <包含作者真实姓名的列表,邮件地址可选>
* :担保人: <担保人的真实姓名>
* :决策人: <决策人的正式姓名>
  :状态: <草稿 | 生效 | 接受 | 临时 | 推迟 | 拒绝 |
           撤回 | 完成 | 已被取代>
  :类型: <标准追踪 | 信息 | 流程>
* :需求: <MEP 编号>
  :创建时间: <MEP 创建时间,格式 YYYY-MM-DD>
* :更新历史: <MEP 更新时间,格式 YYYY-MM-DD, 多次更新用 ``,`` 分隔,较新时间放在前面>
* :已经代替: <MEP 编号>
* :已被代替: <MEP 编号>
* :实现版本: <版本编号>

备注

  • 如果有多位作者,则每个作者都应该一并写在单行中。

  • 个人电子邮件地址将被隐藏,以防止垃圾邮件收集器。

  • 担保人记录由谁(核心开发者或委员会指派)发起当前 MEP 流程,如果 MEP 作者之一是核心开发者,则不需要此字段。

  • 决策人记录由谁(通常由委员会指派)对最终接受或拒绝 MEP 做出决定。

  • MEP 可能有一个“需求”标头,指示此 MEP 所依赖的 MEP 编号。

  • MEP 也可能有一个“已被代替”标头,表明此 MEP 已经被后续文档废弃,并填写代替当前文档的 MEP 编号。

  • 对应地,比较新的 MEP 必须有一个“已经代替”标头,包含已经过时的 MEP 编号。

  • 标准追踪 MEP 通常会有一个“实现版本”标头,表示开始支持该特性的 MegEngine 版本。

报告错误或提交更新#

请使用 GitHub Issues 或 Pull Request 进行讨论和维护(带有 MEPs 标签)确保信息不会丢失。

对 MEP 存储库具有 git push 权限的作者可以通过使用 git push 或 GitHub PR 接口提交他/她(们)的更改来进行更新。

转让 MEP 所有权#

偶尔需要将 MEP 的所有权转让给新的负责人。一般来说,最好保留原作者作为转移后的 MEP 的共同作者,但这实际上取决于原作者。 转让所有权的一个很好的理由是,原作者不再有时间或兴趣更新或遵循 MEP 流程,或者已经脱离了“网络”(即无法访问或不回复电子邮件)。 转让所有权的一个差劲的理由是因为作者不同意 MEP 的后续方向。 MEP 流程的一个目标是尝试围绕 MEP 达成共识,如果难以实现,作者始终可以提交竞争性 MEP.

如果你有兴趣获得 MEP 的所有权,也可以通过拉取请求来实现。Fork 存储库,进行所有权修改,并提交拉取请求。 你应该在对拉取请求的评论中同时提及原作者和 @megvii-mge (如果不知道原作者的 GitHub 用户名,请使用电子邮件)。 如果原作者没有及时回复,MEP 编辑将做出单方面的决定(这种决定也能被撤销)。

MEP 编辑职责和工作流程#

对于编辑器中的每个新 MEP, 请执行以下操作:

  • 确保 MEP 由核心开发者共同撰写,且由核心开发人员或委员会专门为此 MEP 批准的人员作为担保人。

  • 阅读 MEP 以检查它是否准备就绪:健全且完整。这些想法必须具有技术意义,即使不太可能被接受。

  • 标题应准确描述内容。

  • 文件扩展名正确(即 .rst )。

  • 略读 MEP 中语言(拼写、语法、句子结构等)和代码风格的明显缺陷,可以帮助纠正。

如果 MEP 尚未准备好,编辑会将其发回给作者进行修订,并附有具体说明。 如果 reST 格式有问题,请让作者根据 Sphinx reStructuredText 语法入门 中的规定修改并重新提交。

一旦 MEP 准备好用于存储库,MEP 编辑将:

  • 分配一个 MEP 号码(几乎总是下一个可用号码)。

  • 检查作者是否正确标记了 MEP 的类型(“标准追踪”、“信息”或“流程”),并将其状态标记为“草稿”。

  • 将 MEP 添加到 Documetation 存储库的源分支,确保路径正确。

  • 提交并推送全新的(或更新的)MEP.

对现有 MEP 的更新应作为 GitHub 拉取请求进行提交。

许多 MEP 是由对 MegEngine 代码库具有写入权限的开发人员编写和维护的。 MEP 编辑监视 MEP 内容的更改,并更正他/她(们)看到的任何结构、语法、拼写或标记错误。 他/她(们)不会对 MEP 的正确性做出判断,通常负责 MEP 的运营和内容编辑部分。