放弃使用命名空间包¶
https://blueprints.launchpad.net/oslo-incubator/+spec/drop-namespace-packages
将我们的库安装到命名空间包中导致了几种类型的错误。与其继续与之斗争,我建议我们逐步淘汰它们。
问题描述¶
setuptools 中的命名空间包支持很脆弱,并且我们在 OpenStack 中常规使用代码的方式会暴露问题,这些问题很难调试。
我们遇到的主要问题是使用不同的安装“模式”将两个独立的库安装到同一个 python 命名空间包中。如果一个库使用 pip install -e 以启用“可编辑”模式安装,而另一个库没有使用 -e 选项作为常规库安装,那么该包的导入路径就会中断,并且一些已安装的组件将无法导入。当 devstack 以可编辑模式安装 Oslo 库时,这种情况经常发生,我们已经更改了 devstack 以默认情况下停止这样做。当开发人员使用系统包安装某些内容,然后从源代码安装另一个库时也会发生这种情况。我们无法真正控制这种行为,因此它仍然会不时出现。
我们还看到在使用配置为允许访问全局 site-packages 目录的 virtualenvs 时出现问题,就像 nova 需要 libvirt 访问权限一样。如果 oslo 命名空间包中的任何内容都全局安装,它将覆盖 virtualenv 中可见的版本。通常情况下,如果全局安装了旧版本,这会导致版本错误,但在这种情况下,它也可能导致导入错误,因为命名空间包不能正确跨越这两个 site-packages 目录。
提议的变更¶
我建议我们将所有当前的 Oslo 库移出 oslo 命名空间,并创建可以独立导入的简单包。例如,我们将更改
from oslo.foo import bar
变为
from oslo_foo import bar
为了避免与发行版出现问题,我们不应该将 oslo.foo 库重命名为 oslo_foo。这可能会让开发人员感到困惑,因此我们将来可能会重新考虑这个决定,但作为第一步,这不太具侵入性,因为它意味着我们不需要更改我们的需求列表、仓库名称和发行版包名称。
为了支持向后兼容性,我们将为 oslo 命名空间提供 shadow-packages,以便旧的导入形式仍然适用于 Kilo 版本的库。这将给我们时间来更新所有应用程序,并在它们退出长期支持窗口之前,在 M 版本期间完全放弃命名空间包。
迁移到常规包也将允许我们将单元测试移动到库内部,以便它们与 oslo_foo 一起交付和安装,因此我们应该同时进行此操作,仅保留足够的测试套件以确保通过命名空间包公开的公共 API 仍然有效。
现有库的发行名称不会更改,并且将使用相同的模式来创建新库,以避免混淆。这意味着您将 pip install oslo.foo 然后 from oslo_foo import bar。
备选方案¶
lifeless 对 oslo.db 有一个补丁,使用 pkgutils 而不是 setuptools 设置命名空间包
这保留了使用命名空间包的能力,但代价是运送一个真实的
oslo库 (https://github.com/rbtcollins/oslo) 并自行维护覆盖代码。不过,我们不知道可能会发现命名空间包的其他问题,因此我更倾向于完全放弃它们。Python 3 具有更好的原生命名空间包支持,因此当我们将迁移到 Python 3 时,我们可以重新评估此决定。
什么都不做,并继续帮助开发人员调试其系统上的问题。如果选择此选项,我们可能需要编写一个脚本“why_is_oslo_broken.sh”放入 incubator 中。
“oslo_”名称前缀是用来区分库和非生产库(如 oslotest 和 oslosphinx)的。从理论上讲,我们也可以将它们重命名,以便我们所有的品牌库都具有相同的命名约定。我不知道这是否值得这样做。
Impact on Existing APIs¶
导入方式会发生变化,但我们不应该需要更改库 API 的其他方面。
安全影响¶
无
性能影响¶
无
Configuration Impact¶
无
开发人员影响¶
开发人员需要了解导入方式的更改。我们有一些方法可以广泛地传达这些信息
向 oslo 命名空间包添加弃用警告,以便导入它们会报告警告。
添加一个 hacking 规则,使导入“from oslo.” 违法。
依赖审查者来发现它。
选项 1 我们可以自己轻松完成。
选项 2 必须等到我们转换了我们自己的所有库并更新了所有应用程序,但随后可以防止恢复不正确的导入。
选项 3 比较脆弱,所以我不认为我们想仅仅依赖它。
为了方便过渡,我们应该能够准备一个 bash/sed 脚本来对项目进行所需的编辑。我认为我们不会有超过几种不同类型的导入语句,但我们可以根据发现的新模式来更新脚本
Testing Impact¶
单元测试将在每个库中更新,以便所有测试都针对新的模块名称运行。然后,一些公共 API 测试将被复制,以使用命名空间包,以确保我们不会破坏它。
应用程序中现有的单元测试应该涵盖应用程序中库的使用情况。我们需要更新这些测试中的任何模拟对象。
实现¶
负责人¶
- 主要负责人
Doug Hellmann
- 其他贡献者
无
里程碑¶
完成目标里程碑:K-2(我希望尽早)
工作项¶
重新排列我们所有的库代码,包括测试和文档。请参阅 https://review.openstack.org/#/c/127323/ 以获取示例。
为联络员编写辅助脚本(也许联络员可以执行此操作?)。
孵化¶
N/A
采用¶
N/A
库¶
N/A
预计 API 稳定¶
N/A
文档影响¶
无
依赖项¶
无
参考资料¶
setuptools bug 250,“develop 和 –install-single-version-externally-managed 不兼容于命名空间包” - https://bitbucket.org/pypa/setuptools/issue/250/develop-and-install-single-version
lifeless 对 oslo.db 有一个补丁,使用 pkgutils 而不是 setuptools 设置命名空间包
https://review.openstack.org/#/c/123604/3/oslo/__init__.py
它使用一个真实的 oslo 包:https://github.com/rbtcollins/oslo
PEP-420 规范:http://legacy.python.org/dev/peps/pep-0420/
我正在进行的 oslo.i18n 补丁,将其移出命名空间包:https://review.openstack.org/#/c/127323/
Kilo 会议期间的笔记:https://etherpad.openstack.org/p/kilo-oslo-namespace-packages
Kilo 会议后邮件列表主题:http://lists.openstack.org/pipermail/openstack-dev/2014-November/050313.html
注意
本作品采用知识共享署名 3.0 非移植许可协议授权。 http://creativecommons.org/licenses/by/3.0/legalcode