一尘不染

使用distutils / setuptools在安装后执行Python脚本

python

我正在尝试向Pythondistutils添加安装后任务,如如何使用简单的安装后脚本扩展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},
)

这种方法有效,但是据我所知有两个缺陷:

  1. 如果用户使用的Python解释器不是从中选择的PATH,则将使用 其他 解释器执行安装后脚本,这可能会引起问题。
  2. 这对于防止空运行等并不安全,我可以通过将其包装在函数中并使用来进行补救distutils.cmd.Command.execute

我该如何改善解决方案?有推荐的方法/最佳做法吗?如果可能,我想避免引入其他依赖项。


阅读 167

收藏
2020-12-20

共1个答案

一尘不染

解决这些缺陷的方法是:

  1. 获取setup.py从执行的Python解释器的完整路径sys.executable
  2. 继承自的类distutils.cmd.Command(例如distutils.command.install.install我们在此处使用的类)实现该execute方法,该方法以“安全方式”(即尊重空运行标志)执行给定功能。

但是请注意,--dry-run选项当前已损坏,无论如何都无法正常工作。

我得到了以下解决方案:

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将使用。

2020-12-20