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

kyn*_*nan 29 python install distutils setuptools post-install

我正在尝试向Python distutils添加安装后任务,如如何使用简单的安装后脚本扩展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},
)
Run Code Online (Sandbox Code Playgroud)

这种方法有效,但据我所知,有两个不足之处:

  1. 如果用户使用的Python解释器不是拾取者PATH,则安装后脚本将使用不同的解释器执行,这可能会导致问题.
  2. 它对于干运行等是不安全的,我可以通过将其包装在一个函数中并使用它来解决它distutils.cmd.Command.execute.

我怎样才能改进我的解决方案?这样做有推荐的方法/最佳做法吗?如果可能的话,我想避免引入另一个依赖.

kyn*_*nan 34

解决这些不足的方法是:

  1. 获取的完整路径,Python解释器执行setup.pysys.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},
)
Run Code Online (Sandbox Code Playgroud)

请注意,我使用类名install作为派生类,因为python setup.py --help-commands它将使用.