我正在尝试按照How to extend distutils with a simple post install script?中的说明向Python distutils添加安装后任务。该任务应该在已安装的lib目录中执行Python脚本 。该脚本生成安装包所需的其他Python模块。
我的第一次尝试如下:
from distutils.core import setup
from distutils.command.install import install
class post_install(install):
def run(self):
install.run(self)
from subprocess import call
call(['python', 'scriptname.py'],
cwd=self.install_lib + 'packagename')
setup(
...
cmdclass={'install': post_install},
)
这种方法有效,但据我所知,有两个不足之处:
PATH
获取的解释器,则安装后脚本将使用不同的解释器执行,这可能会导致问题。distutils.cmd.Command.execute
调用它来解决这个问题。我如何改进我的解决方案?这样做有推荐的方法/最佳做法吗?如果可能的话,我想避免引入另一个依赖。
答案 0 :(得分:34)
解决这些不足的方法是:
setup.py
获取执行sys.executable
的Python解释器的完整路径。从distutils.cmd.Command
继承的类(例如我们在这里使用的distutils.command.install.install
)实现了execute
方法,该方法以“安全的方式”执行给定的函数,即尊重干涸的旗帜。
但请注意the --dry-run
option is currently broken并且无论如何都无法正常工作。
我最终得到了以下解决方案:
import os, sys
from distutils.core import setup
from distutils.command.install import install as _install
def _post_install(dir):
from subprocess import call
call([sys.executable, 'scriptname.py'],
cwd=os.path.join(dir, 'packagename'))
class install(_install):
def run(self):
_install.run(self)
self.execute(_post_install, (self.install_lib,),
msg="Running post install task")
setup(
...
cmdclass={'install': install},
)
请注意,我使用类名install
作为派生类,因为这是python setup.py --help-commands
将使用的。
答案 1 :(得分:1)
我认为执行安装后并保持要求的最简单方法是装饰对setup(...)
的调用:
from setup tools import setup
def _post_install(setup):
def _post_actions():
do_things()
_post_actions()
return setup
setup = _post_install(
setup(
name='NAME',
install_requires=['...
)
)
在声明setup()
时,这将运行setup
。完成需求安装后,它将运行_post_install()
函数,该函数将运行内部函数_post_actions()
。