主要观点:随着uv的快速发展,开始重新研究为 Python 实现多版本导入。目标是让求解器能够在 uv 中进行多种解析,以便同时安装和使用两个不兼容版本的库。
关键信息:
- Python 的导入系统将模块置于模块缓存中,通过
sys.modules暴露。 - 不同版本的库在
sys.modules中可能会冲突,需将多版本包放置在不同位置,并使用自定义导入钩子导入。 - 需根据调用包的包元数据来确定导入的库版本,目前存在导入钩子不知哪个模块触发导入、Python 模块不知其分发包等挑战。
- 要确定调用的 Python 模块及相关的 PyPI 分发名称,目前的
importlib.metadata.packages_distributions方法有局限性。
重要细节: foo.py是 Python“模块”,在sys.modules中注册为'foo',foo/__init__.py既是模块也是包,有__path__和__package__属性。- 分发包可包含多个模块,如
whatever包包含foo.py和bar/baz.py。 - 多版本包放置在
.venv/multi-version-packages/下,需自定义导入钩子并注册代理以解决sys.modules中的问题。 - 解决确定导入版本的问题需利用
globals()获取导入模块的包名,对于 C 扩展需通过栈回溯或携带当前活动的 C 扩展模块来确定触发导入的.so/.dylib文件。 - 目前缺乏将
sys.module条目与 PyPI 分发名称映射的 API,安装器可能需将分发名称关联到模块上。 - 端到端解决方案包括将多版本包安装在
site-packages外,在模块上实现__distribution__字段或提供映射 API,修补__import__函数,以及在sys.modules中注册代理条目。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用。你还可以使用@来通知其他用户。