2013-07-23 45 views
27

我正在尝试向Python distutils添加后安装任务,如How to extend distutils with a simple post install script?中所述。该任务应该在已安装的lib目录中执行Python脚本。该脚本生成安装软件包所需的其他Python模块。使用distutils/setuptools执行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来调用它来弥补。

我该如何改进我的解决方案?有没有推荐的方法/最佳做法?如果可能的话,我想避免拉入另一个依赖项。

+0

对于那些希望能够使用'python setup.py install'以及'pip install'的用户,请参阅:http://stackoverflow.com/questions/21915469/python-setuptools-install-requires -is-ignored-when-overriding-cmdclass –

回答

34

解决这些deficiences的方法是:

  1. 获取对Python解释器从sys.executable执行setup.py的完整路径。
  2. 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会用什么。

+0

谢谢,这确实有帮助,我也需要遵循(http://stackoverflow.com/questions/15853058/run-custom-task-when-call-pip-install)避免在我的pip安装中出现错误。我把它们放在博客文章中(http://diffbrent.ghost.io/correctly-adding-nltk-to-your-python-package-using-setup-py-post-install-commands/)。让我知道如果我错过了什么。 –

+0

@ brent.payne很高兴听到它的帮助!注意我为什么使用'install'作为类名的评论。 – kynan

+1

它可以工作,但我无法使用'pip install -e name'执行自定义安装。 ps,刚刚找到[此链接](http://www.niteoweb.com/blog/setuptools-run-custom-code-during-install),请参阅BONUS部分。 – Paolo