Mik*_*cre 6 python linux setuptools
我为使用模块(https://luarocks.org/)管理软件包的系统编写了小型python 软件包。对于那些不了解它的人,可以运行module load x并运行一个小的脚本来修改各种环境变量以使软件“ x”正常工作,然后可以使用撤消该操作module unload x。
这种软件管理方法在科学计算中几乎无处不在,并且在该领域具有很大的价值:您可以将古老的未维护软件与该软件可能会干扰的软件包一起运行,可以运行多个版本的软件,从而使自己的产品再现。准确地记录数据(您可以返回到旧版本),并且可以运行具有过时依赖关系的坦率地编写未更新的软件。
这些功能很棒,但是它们在python 2/3 split中造成了问题:
如果您想编写一个同时适用于python 2和3 的软件包并将其与需要 python 2或3的软件一起使用怎么办?
使旧的python2依赖软件在这些大型系统上工作的方式是,您制作了python / 2.7.x模块和python / 3.5模块。当您要运行使用python 2的脚本时,请加载该模块等。
但是,我想编写一个可以在两种环境下都可以使用的python软件包,因为无论使用哪种python解释器,我都希望该软件处于活动状态。
从根本上讲,这非常容易:只需使用#!/usr/bin/env pythonshebang线就可以了。这样可行。我编写了所有软件都可以使用,所以没有问题。
问题是:我想使用setuptools将我的软件包分发给处于相同情况的其他科学家,而setup工具会破坏shebang线。
我不想就修改shebang线是否是一个好主意展开辩论,我相信这是因为它已经在同一状态下存在多年了。老实说,我不在乎,这对我不起作用。默认的setuptools安装会导致软件无法运行,因为当未加载python解释器的模块时,该python解释器将无法运行,这PYTHONPATH是完全错误的。
如果我所有的用户都具有root用户访问权限,则可以使用该data_files选项将脚本复制到/usr/bin,但这对兼容性不是一个好主意,而且我的用户也没有root用户访问权限,因此这是一个有争议的问题。
到目前为止,我尝试过的事情:
我尝试设置sys.executable到/usr/bin/env python中setup.py文件,但不起作用,因为那时家当是:#!"/usr/bin/env python",这显然是行不通的。
我在以下问题中尝试了“不要触碰我的shebang类”想法:不要触碰我的shebang!(这是最低的答案,票数为0)。那也不起作用,可能是因为它是为distutils而不是setuptools编写的。再加上这个问题已有6年历史了。
我还看了这些问题:
Setuptools entry_points / console_scripts在shebang中具有特定的Python版本
那里描述的方法不起作用,shebang线仍被更改。
创建一个setup.cfg包含以下内容的文件:
[build]
executable = /usr/bin/env python
Run Code Online (Sandbox Code Playgroud)
也不会改变shebang行的行为。
setuptools github页面上有一个未解决的问题,讨论了类似的内容:
https://github.com/pypa/setuptools/issues/494
因此,我认为这不可能在本地完成,但是我想知道是否有解决方法?
最后,我不喜欢任何涉及要求用户修改安装标志的解决方案,例如使用-e。
无论如何,是否可以修改此行为,或者可以使用其他发行系统代替?还是这太过分了,我只需要编写某种自定义安装脚本即可?
谢谢大家
我想我对最初的问题还不够清楚,我希望用户能够做到的是:
如果有一种方法可以在不阻止shebang干扰的情况下做到这一点,那就太好了。
我所有的代码已经与python 2.7和python 3.3+兼容,即装即用,主要目的是使脚本无论运行的python环境如何都可以运行。
我在尝试编写自定义安装脚本时无意中发现了一种解决方法。
import os
from setuptools import setup
from setuptools.command.install import install
here = os.path.abspath(os.path.dirname(__file__))
# Generate a list of python scripts
scpts = []
scpt_dir = os.listdir(os.path.join(here, 'bin'))
for scpt in scpt_dir:
scpts.append(os.path.join(here, 'bin', scpt))
class ScriptInstaller(install):
"""Install scripts directly."""
def run(self):
"""Wrapper for parent run."""
super(ScriptInstaller, self).run()
setup(
cmdclass={'install': ScriptInstaller},
scripts=scpts,
...
)
Run Code Online (Sandbox Code Playgroud)
这段代码并没有完全达到我想要的效果(只改变 shebang 行),它实际上只是将整个脚本复制到~/.local/bin,而不是将其包装在::
__import__('pkg_resources').run_script()
Run Code Online (Sandbox Code Playgroud)
此外,更令人担忧的是,此方法使 setuptools 创建一个根模块目录和一个 Egg-info 目录,如下所示:
.local/lib/python3.5/site-packages/cluster
.local/lib/python3.5/site-packages/python_cluster-0.6.1-py3.5.egg-info
Run Code Online (Sandbox Code Playgroud)
而不是一个鸡蛋,这是通常的行为::
.local/lib/python3.5/site-packages/python_cluster-0.6.1-py3.5.egg
Run Code Online (Sandbox Code Playgroud)
据我所知,这是旧 distutils 的行为,这让我担心此安装会在某些系统上失败或出现其他意外行为(尽管如果我错了,请纠正我,我真的不是这方面的专家) 。
然而,考虑到我的代码几乎完全在 Linux 和 OS X 上使用,这并不是世界末日。我更担心这种行为很快就会消失。
我在 setuptools github 页面上发布了对开放功能请求的评论:
https://github.com/pypa/setuptools/issues/494
理想的解决方案是,如果我可以executable=/usr/bin/env python向 setup.cfg 添加一条语句,希望很快就能重新实现。
不过,这个解决方法目前对我有用。谢谢大家。
| 归档时间: |
|
| 查看次数: |
966 次 |
| 最近记录: |