我最近与pex 发生了争执,试图使其包含本地模块。我学到的是:
- 您必须为您的模块提供一个有效的
setup.py 文件,这样才能正常工作,并且:
- 您必须指定应用程序的入口点
这有几个原因很难弄清楚。通过阅读文档,我能够推断出在我的案例中正确的命令应该是这样的:
$ pex . -v -e usersnotifier:main -o usersnotifier.pex
但是,当我尝试这样做时,我一直收到错误消息:
pex.resolvable.InvalidRequirement: Unknown requirement type: .
出现了针对此错误的网络搜索——因为它的第一个命中——this Github issue,在我输入时它仍然处于打开状态。由于这个错误,A 花了很长时间认为上述命令不起作用。在this SO answer 暗示有必要提供setup.py 文件之前,我尝试降级setuptools 并进行了六次其他徒劳的尝试来“解决”该问题。 (那个 Github 问题原来是一个红鲱鱼。据我所知,它提到的 setuptools 错误已得到修复。)
所以...我写了一个setup.py 文件。起初,我一直收到 Unknown requirement type: . 的错误消息,但后来我意识到我的 setup.py 只是包含一个非常明显的印刷错误。在这种情况下,pex 发出的错误消息实际上非常清楚,但随后是一个大的堆栈跟踪和Unknown requirement type: . 消息。我只是没有密切关注,错过的时间比我愿意承认的要长。
我终于注意到了我的错字并修复了它,但是我的setup.py 中的另一个缺陷未能包含我的本地模块。 pex 在这种情况下有效,但生成的文件没有:
$ pex . -v -e usersnotifier:main -o usersnotifier.pex --disable-cache
usersnotifier 0.1: Resolving distributions :: Packaging paho-mqtt
pyinotify 0.9.6
paho-mqtt 1.3.1
pex: Building pex: 2704.3ms
pex: Resolving distributions: 2393.2ms
pex: Packaging usersnotifier: 319.3ms
pex: Packaging pyinotify: 347.4ms
pex: Packaging paho-mqtt: 361.1ms
Saving PEX file to usersnotifier.pex
$ ./usersnotifier.pex
Traceback (most recent call last):
File ".bootstrap/_pex/pex.py", line 367, in execute
File ".bootstrap/_pex/pex.py", line 293, in _wrap_coverage
File ".bootstrap/_pex/pex.py", line 325, in _wrap_profiling
File ".bootstrap/_pex/pex.py", line 410, in _execute
File ".bootstrap/_pex/pex.py", line 468, in execute_entry
File ".bootstrap/_pex/pex.py", line 482, in execute_pkg_resources
File ".bootstrap/pkg_resources/__init__.py", line 2297, in resolve
ImportError: No module named 'usersnotifier'
这是最终对我有用的基本setup.py:
from setuptools import setup
setup(
name='usersnotifier',
version='0.1',
py_modules=['usersnotifier', 'userswatcher'],
install_requires=[
'paho-mqtt>=1.3.1',
'pyinotify>=0.9.6',
],
include_package_data=True,
zip_safe=False
)
它之前不起作用的原因是我不小心将参数py_module 传递给setup() 而不是py_modules(复数)。 ¯\_(ツ)_/¯
@cmcginty 对这个问题的回答中提到了我遇到的最后一个障碍,即:除非您的模块版本号发生更改,否则pex 将缓存/重用您上次运行它时的工件。因此,如果您修复 setup.py 中的问题并重新运行 pex,它实际上不会合并您的更改,除非您:a) 修改版本号,或 b) 在调用 pex 时传递 --disable-cache .
最后,整个事情变成了一个练习,写一个正确的setup.py,然后运行:
$ pex . -v -e mymodule:main -o mymodule.pex --disable-cache
以下是我可以提供的一些提示(可能是给未来的我自己):
提示 1
使用python setup.py sdist 测试您的setup.py 文件。 出人意料地很容易搞砸,除非你确定你的包裹有正确的内容,否则涉及pex 是没有意义的。运行python setup.py sdist 后,尝试将它生成的源包(位于dist 文件夹中)安装到一个新的venv 中,看看它是否包含您期望的所有文件。 之后才可以继续调用pex。
提示 2
总是将--disable-cache 传递给pex,除非你有充分的理由不这样做。
提示 3
在解决所有这些问题时,我发现我可以运行:
$ unzip mymodule.pex
提取 PEX 文件的内容。这有助于解决 sdist 包内容与 pex 化应用程序之间存在的任何差异。