2013-07-23 48 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