首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用pex封装本地模块

用pex封装本地模块
EN

Stack Overflow用户
提问于 2016-11-07 16:34:13
回答 3查看 6.2K关注 0票数 8

我正在尝试用pex打包我的本地模块,但我似乎无法做到。

我创建了一个简单的项目:

代码语言:javascript
复制
→ python --version
Python 2.7.10
→ pex --version
pex 1.1.15
→ tree .
.
├── bla
│   ├── __init__.py
│   └── main.py
└── setup.py

bla/__init__.py

代码语言:javascript
复制
import main

bla/main.py

代码语言:javascript
复制
if __name__ == '__main__':
   print 'yo'

对我来说这似乎是最简单的计划。

代码语言:javascript
复制
→ 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,但是这失败了,因为它找不到命令。

我好像误解了一些基本的东西,但我想不出是什么。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-03-29 22:03:08

最近,我和pex吵了一架,想让它包括本地模块。我学到的是:

  1. 您必须为模块提供一个有效的setup.py文件才能工作,并且:
  2. 必须指定应用程序的入口点

这是一个棘手的问题,原因有几个。通过阅读文档,我可以推断,在我的情况下,正确的命令应该如下所示:

代码语言:javascript
复制
$ pex . -v -e usersnotifier:main -o usersnotifier.pex

但是,当我尝试这样做时,我一直收到一个错误:

代码语言:javascript
复制
pex.resolvable.InvalidRequirement: Unknown requirement type: .

对此错误的web搜索--这是它的第一次点击--这个吉特布问题,在我键入此错误时仍然处于打开状态。A花了很长时间认为上面的命令因为这个错误而不能工作。我试图降低setuptools的级别,并在这就是答案暗示提供setup.py文件的必要性之前,做了六次“修复”这个问题的尝试,但都没有结果。(那个吉特布的问题被证明是一只红鲱鱼。据我所知,它提到的setuptools bug已经修复。)

所以..。我写了一个setup.py文件。起初,我一直在说Unknown requirement type: .的错误,但后来我意识到,我的setup.py只是包含一个非常明显的排印错误。在本例中,pex发出的错误消息实际上非常清楚,但后面是一个大的ish堆栈跟踪和Unknown requirement type: .消息。我只是没有密切注意,错过的时间超过了我愿意承认的时间。

我终于注意到了我的错误并修复了它,但是我的setup.py中的另一个缺陷是没有包括我的本地模块。pex在这种情况下工作,但是生成的文件没有:

代码语言:javascript
复制
$ 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

代码语言:javascript
复制
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的练习,并运行:

代码语言:javascript
复制
$ 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

在排除所有这些问题时,我发现可以运行:

代码语言:javascript
复制
$ unzip mymodule.pex

要提取PEX文件的内容,请执行以下操作。这可能有助于解决您的sdist包内容和您的pex化应用程序之间的任何差异。

票数 11
EN

Stack Overflow用户

发布于 2016-11-09 06:03:24

一种方法是:

  1. 创建一个源发行版(tarball、zip文件等)使用python setup.py sdist
  2. 然后使用pex开关运行-f DIST_DIR命令 例如:pex $(pip freeze) -o aflaskapp.pex -e 'aflaskapp.app' -f dist -v
票数 3
EN

Stack Overflow用户

发布于 2018-03-21 18:33:30

我发现了更多的细节。如果你跑:

代码语言:javascript
复制
pex .

它将尝试在目录中使用setup.py构建。如果没有,那么pex就会失败。

默认情况下,pex将缓存本地包输出,因此如果更改setup.py,则使用命令确保在下一次pex运行时应用更改。

代码语言:javascript
复制
pex . --disable-cache
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40470046

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档