用pex打包本地模块
Packaging local module with pex
我正在尝试用 pex 打包我的本地模块,但我似乎做不到。
我创建了一个简单的项目:
→ python --version
Python 2.7.10
→ pex --version
pex 1.1.15
→ tree .
.
├── bla
│ ├── __init__.py
│ └── main.py
└── setup.py
bla/__init__.py
import main
bla/main.py
if __name__ == '__main__':
print 'yo'
这对我来说似乎是最简单的项目。
→ pex -v . -o v.pex --disable-cache
Traceback (most recent call last):
File "/Users/Charly/repos/load_tester/venv/bin/pex", line 11, in <module>
sys.exit(main())
File "/Users/Charly/repos/load_tester/venv/lib/python2.7/site-packages/pex/bin/pex.py", line 540, in main
pex_builder = build_pex(reqs, options, resolver_options_builder)
File "/Users/Charly/repos/load_tester/venv/lib/python2.7/site-packages/pex/bin/pex.py", line 475, in build_pex
resolvables = [Resolvable.get(arg, resolver_option_builder) for arg in args]
File "/Users/Charly/repos/load_tester/venv/lib/python2.7/site-packages/pex/resolvable.py", line 61, in get
raise cls.InvalidRequirement('Unknown requirement type: %s' % resolvable_string)
pex.resolvable.InvalidRequirement: Unknown requirement type: .
也尝试过 python setup.py bdist_pex
但是失败了,因为找不到命令。
我好像真的误解了一些基本的东西,但我想不通。
一种方法是:
- create 使用
python setup.py sdist
创建源分发(tarball、zip 文件等)
然后 运行 pex
命令与 -f DIST_DIR
开关
例如。 pex $(pip freeze) -o aflaskapp.pex -e 'aflaskapp.app' -f dist -v
我发现了一些额外的细节。如果你 运行:
pex .
它将尝试使用目录中的 setup.py
构建。如果没有,那么 pex
将失败。
默认情况下,pex
将缓存本地包输出,因此如果您更改 setup.py
然后使用命令确保您的更改应用到下一个 pex
运行.
pex . --disable-cache
我最近与 pex
试图让它包含本地模块发生了一些争执。我学到的是:
- 您必须为您的模块提供一个有效的
setup.py
文件才能使它工作,并且:
- 您必须指定应用程序的入口点
由于多种原因,这很难弄清楚。通过阅读文档,我能够推断出在我的案例中正确的命令应该是这样的:
$ pex . -v -e usersnotifier:main -o usersnotifier.pex
但是,当我尝试这样做时,我一直收到错误提示:
pex.resolvable.InvalidRequirement: Unknown requirement type: .
针对此错误的网络搜索出现了——因为它 第一次 命中——this Github issue, which is still open as I type this. A spent a long while thinking that the above command wasn't working because of this bug. I attempted to downgrade setuptools and made a half-dozen other fruitless attempts to 'fix' the problem before this SO answer 暗示有必要提供 setup.py
文件。 (那个 Github 问题原来是一个转移注意力的问题。据我所知,它提到的 setuptools
错误已经被修复。)
所以...我写了一个 setup.py
文件。起初,我一直收到 Unknown requirement type: .
错误,但后来我意识到我的 setup.py
只是包含一个 dead-obvious 印刷错误。在这种情况下,pex 发出的错误消息实际上非常清楚,但紧随其后的是 large-ish 堆栈跟踪和 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'
这是最终对我有用的 bare-bones 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
将 cache/reuse 上次您 运行 它。因此,如果您修复 setup.py
和 re-run pex
中的问题,它实际上不会合并您的更改,除非您:a) 修改版本号,或 b) 通过 --disable-cache
调用时 pex
.
在一天结束的时候,整个事情变成了一个练习,写一个合适的 setup.py
,运行ning:
$ pex . -v -e mymodule:main -o mymodule.pex --disable-cache
以下是我可以提供的一些技巧(可能是给未来的我):
提示 1
使用 python setup.py sdist
测试您的 setup.py
文件。令人惊讶的是 很容易搞砸,在您确定您的包裹内容正确之前,涉及 pex
毫无意义。在 运行ning python setup.py sdist
之后,尝试将它生成的源码包(位于 dist
文件夹中)安装到一个新的 venv 中,看看它是否包含您期望的所有文件。只有在 pex
之后才继续调用 这是有效的。
提示 2
总是 将 --disable-cache
传递给 pex
除非你有充分的理由不这样做。
提示 3
在解决所有这些问题时,我发现我可以 运行:
$ unzip mymodule.pex
提取PEX文件的内容。这有助于解决 sdist 包内容与 pex-ified 应用程序之间存在的任何差异。
我正在尝试用 pex 打包我的本地模块,但我似乎做不到。
我创建了一个简单的项目:
→ python --version
Python 2.7.10
→ pex --version
pex 1.1.15
→ tree .
.
├── bla
│ ├── __init__.py
│ └── main.py
└── setup.py
bla/__init__.py
import main
bla/main.py
if __name__ == '__main__':
print 'yo'
这对我来说似乎是最简单的项目。
→ pex -v . -o v.pex --disable-cache
Traceback (most recent call last):
File "/Users/Charly/repos/load_tester/venv/bin/pex", line 11, in <module>
sys.exit(main())
File "/Users/Charly/repos/load_tester/venv/lib/python2.7/site-packages/pex/bin/pex.py", line 540, in main
pex_builder = build_pex(reqs, options, resolver_options_builder)
File "/Users/Charly/repos/load_tester/venv/lib/python2.7/site-packages/pex/bin/pex.py", line 475, in build_pex
resolvables = [Resolvable.get(arg, resolver_option_builder) for arg in args]
File "/Users/Charly/repos/load_tester/venv/lib/python2.7/site-packages/pex/resolvable.py", line 61, in get
raise cls.InvalidRequirement('Unknown requirement type: %s' % resolvable_string)
pex.resolvable.InvalidRequirement: Unknown requirement type: .
也尝试过 python setup.py bdist_pex
但是失败了,因为找不到命令。
我好像真的误解了一些基本的东西,但我想不通。
一种方法是:
- create 使用
python setup.py sdist
创建源分发(tarball、zip 文件等)
然后 运行
pex
命令与-f DIST_DIR
开关例如。
pex $(pip freeze) -o aflaskapp.pex -e 'aflaskapp.app' -f dist -v
我发现了一些额外的细节。如果你 运行:
pex .
它将尝试使用目录中的 setup.py
构建。如果没有,那么 pex
将失败。
默认情况下,pex
将缓存本地包输出,因此如果您更改 setup.py
然后使用命令确保您的更改应用到下一个 pex
运行.
pex . --disable-cache
我最近与 pex
试图让它包含本地模块发生了一些争执。我学到的是:
- 您必须为您的模块提供一个有效的
setup.py
文件才能使它工作,并且: - 您必须指定应用程序的入口点
由于多种原因,这很难弄清楚。通过阅读文档,我能够推断出在我的案例中正确的命令应该是这样的:
$ pex . -v -e usersnotifier:main -o usersnotifier.pex
但是,当我尝试这样做时,我一直收到错误提示:
pex.resolvable.InvalidRequirement: Unknown requirement type: .
针对此错误的网络搜索出现了——因为它 第一次 命中——this Github issue, which is still open as I type this. A spent a long while thinking that the above command wasn't working because of this bug. I attempted to downgrade setuptools and made a half-dozen other fruitless attempts to 'fix' the problem before this SO answer 暗示有必要提供 setup.py
文件。 (那个 Github 问题原来是一个转移注意力的问题。据我所知,它提到的 setuptools
错误已经被修复。)
所以...我写了一个 setup.py
文件。起初,我一直收到 Unknown requirement type: .
错误,但后来我意识到我的 setup.py
只是包含一个 dead-obvious 印刷错误。在这种情况下,pex 发出的错误消息实际上非常清楚,但紧随其后的是 large-ish 堆栈跟踪和 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'
这是最终对我有用的 bare-bones 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
将 cache/reuse 上次您 运行 它。因此,如果您修复 setup.py
和 re-run pex
中的问题,它实际上不会合并您的更改,除非您:a) 修改版本号,或 b) 通过 --disable-cache
调用时 pex
.
在一天结束的时候,整个事情变成了一个练习,写一个合适的 setup.py
,运行ning:
$ pex . -v -e mymodule:main -o mymodule.pex --disable-cache
以下是我可以提供的一些技巧(可能是给未来的我):
提示 1
使用 python setup.py sdist
测试您的 setup.py
文件。令人惊讶的是 很容易搞砸,在您确定您的包裹内容正确之前,涉及 pex
毫无意义。在 运行ning python setup.py sdist
之后,尝试将它生成的源码包(位于 dist
文件夹中)安装到一个新的 venv 中,看看它是否包含您期望的所有文件。只有在 pex
之后才继续调用 这是有效的。
提示 2
总是 将 --disable-cache
传递给 pex
除非你有充分的理由不这样做。
提示 3
在解决所有这些问题时,我发现我可以 运行:
$ unzip mymodule.pex
提取PEX文件的内容。这有助于解决 sdist 包内容与 pex-ified 应用程序之间存在的任何差异。