仓库源文

上文中的两个问题之一,是发布到 PyPI 的版本(即 pip install ulang)在运行时有个测试未通过:测试/引用/引用本地包内py.ul,而开发版和木兰原始可执行文件是通过的。

由于这是第一次发觉 PyPI 发布版本的行为差异,于是优先研究。

问题描述

测试源码如下:

using test.package.module_py
test.package.module_py.talk()

在项目根目录下(后文如无特别说明,命令运行都在根目录下),有如下测试包结构:

开发版如下运行测试无误:

$ python3 -m 木兰 测试/引用/引用本地包内py.ul

但如果安装在 PyPI 的发布版,再如下运行相同测试用例则报错(见此 issue):

$ 木兰 测试/引用/引用本地包内py.ul
 😰 没找到模块:‘test.package’
调用层级如下
见第1行:using test.package.module_py

但是,发布版如下引用当前目录下的模块并无问题:

using test_module_py
test_module_py.talk()

为何?

调查过程

由于木兰原始可执行文件运行该测试无误,于是首先对木兰重现项目用 PyInstaller 生成(参考前文)exe 文件进行测试,引用并无问题。

由于无头绪,建立最简项目重现问题,再次确认当前运行目录需添加到 sys.path 才能引用当前目录下的模块 test_module_py(在此前的 commit 中实现)。接下去围绕 sys.path 做一系列测试。

期间试着将 test 目录改名为 tes,结果引用成功。又直接使用 print(__import__('test')),才发现在 Python3 的包路径中,原就存在一个 test 包。

结论

sys.path 在不同运行版本的区别如下:

由此来看重现项目两种发布版的优劣势: