我讨厌distutils(我猜he is the evil who does this)的一件事是它改变了shebang线。换句话说,更合理的环境变量决定了经文
#!/usr/bin/env python
神奇地转换为
#!/whatever/absolute/path/is/my/python
在grok中也可以看到这一点:我在virtualenv中使用了grokproject来启动我的项目,但是现在我不能再将开发目录移动了,因为它将绝对路径放在shebang指令中。
我之所以这样问是双重的
答案 0 :(得分:14)
当然,您可以移动开发目录。 Distutils会更改运行它时应运行的python路径。运行buildout时,它在Grok运行中。移动并重新运行引导程序和构建。完成!
Distutils更改了用于运行distutils的Python的路径。如果没有,那么你最终可能会在一个python版本中安装一个库,但是当你尝试运行脚本时它会失败,因为它会运行另一个没有库的python版本。
这不是疯狂,它实际上是唯一理智的方式。
更新: 如果您知道自己在做什么,可以这样做:
/path/to/install/python setup.py build -e "/the/path/you/want/python" install
请确保先清理构建目录。 :)
答案 1 :(得分:10)
Distutils会自动将shebang替换为用于执行setup.py的Python二进制文件的位置。要覆盖此行为,您有两个选择:
选项1:手动
您可以将标志 - executable = / path /传递给/ my / python 到setup.py。参数被接受。
示例:
% python setup.py build --executable=/opt/local/bin/python -d
选项2:自动
您的另一个选择是在setup.cfg中添加一行。如果您不使用setup.cfg,请在setup.py所在的目录中创建它。 Setup.py在启动时查找此内容。此处指定的任何选项仍可在命令行中使用标记覆盖。
% cat setup.cfg
[build]
executable = /opt/local/bin/python -d
答案 2 :(得分:2)
我没有解决您问题的方法,但我确实看到了 distutils 当前行为的一些基本原理。
#!/usr/bin/env python
执行系统的默认Python版本。只要您的代码与所述版本兼容,那就没问题。更新默认版本时(例如,从2.5到3),即使仍安装了旧的Python版本,引用/usr/bin/env
的代码或其他Python代码也可能无法正常工作。出于这个原因,“硬编码”到适当的python解释器的路径是有意义的。
编辑:您断言指定python2.4
或类似问题可以解决此问题。
编辑2:当存在多个相同Python版本的安装时,事情并不明确,正如Ned Deily在下面的评论中指出的那样。
答案 3 :(得分:2)
在 distutils 的最新版本中,有一个标志 - no-autoreq 对我有用:
--no-autoreq do not automatically calculate dependencies
就我而言,我在一个安装了2.4和2.6的服务器上创建了带有python2.4可执行文件的RPM文件。在跑完之后,bdist刚刚离开了shebangs:
python setup.py bdist_rpm --no-autoreq
如果您正在处理规范文件,则可以使用https://stackoverflow.com/a/7423994/722997中解释的解决方案,添加:
AutoReq: no
答案 4 :(得分:1)
有同样的问题。试图找到一种方法来默认完全阻止触摸。这是解决方案。基本上我们覆盖默认的脚本复制例程(build_scripts)。
在setup.py中添加
from distutils.command.build_scripts import build_scripts
# don't touch my shebang
class BSCommand (build_scripts):
def run(self):
"""
Copy, chmod each script listed in 'self.scripts'
essentially this is the stripped
distutils.command.build_scripts.copy_scripts()
routine
"""
from stat import ST_MODE
from distutils.dep_util import newer
from distutils import log
import os
self.mkpath(self.build_dir)
outfiles = []
for script in self.scripts:
outfile = os.path.join(self.build_dir, os.path.basename(script))
outfiles.append(outfile)
if not self.force and not newer(script, outfile):
log.debug("not copying %s (up-to-date)", script)
continue
log.info("copying and NOT adjusting %s -> %s", script,
self.build_dir)
self.copy_file(script, outfile)
if os.name == 'posix':
for file in outfiles:
if self.dry_run:
log.info("changing mode of %s", file)
else:
oldmode = os.stat(file)[ST_MODE] & 0o7777
newmode = (oldmode | 0o555) & 0o7777
if newmode != oldmode:
log.info("changing mode of %s from %o to %o",
file, oldmode, newmode)
os.chmod(file, newmode)
setup(name="name",
version=version_string,
description="desc",
...
test_suite='testing',
cmdclass={'build_scripts': BSCommand},
)
.. ede / duply.net