2013-03-17 20 views
5

我有一個包含配置文件和聯機幫助頁的Python軟件。要安裝這些,我在我的setup.py以下行(如在http://docs.python.org/2/distutils/setupscript.html#installing-additional-files描述):如何在軟件包安裝期間測試Python是否從virtualenv運行

data_files = [('/etc/foo', ['foo.conf']), ('/usr/share/man/man1', ['foo.1'])] 

,當我想用​​python setup.py install安裝軟件的根這工作得很好,但當然不能以virtualenv中,因爲用戶不允許寫入/etc/usr/share/man

解決這個問題的最佳做法是什麼?在當前環境中檢查VIRTUAL_ENV,只是不安裝這些文件?該軟件將在本地目錄中查找foo.conf,這樣應該沒問題。用戶可能會錯過手冊頁,但是沒有任何安裝它的方法,因爲man不會在virtualenv附近的任何地方查找它。

+3

我沒有一個完整的答案給你的問題,但檢查VIRTUAL_ENV是不可靠的,因爲你也可以從virtualenv的bin目錄顯式運行「python」二進制文件來獲得相同的效果。 – 2013-03-17 21:12:26

+0

@MartinAtkins肯定?實際的二進制文件是相同的:'md5sum/tmp/bar/bin/python/usr/bin/python b35da8492c4ddb3e3413411e574db63a/tmp/bar/bin/python b35da8492c4ddb3e3413411e574db63a/usr/bin/python'。 而我的理解是,我*有*通過採購'bin/activate'激活env。 – zhenech 2013-03-17 21:19:07

+1

不,你不必激活環境。你可以'cd/path/to/virtualenv'然後'bin/python'就好了。 – 2013-03-17 21:23:53

回答

9

最終,你的問題看起來真的是關於如何檢測運行中的Python是否在virtualenv中。要了解這一點,我們必須瞭解virtualenv的實際工作原理。

當您運行的virtualenv內activate腳本,它做了兩兩件事:

  • 它更新PATH環境變量,包括從virtualenv中的bin目錄,這樣,當你從運行python二進制virtualenv將運行。
  • 它設置變量VIRTUAL_ENV以便激活腳本本身可以跟蹤激活。

這是完全可以接受的直接運行在virtualenv中的python,並在運行時python完全不使用VIRTUAL_ENV變量。而是確定包含正在運行的python二進制文件的目錄,並使用父目錄作爲其「前綴」。

您可以通過導入sys模塊和諮詢sys.prefix來確定系統的前綴。然而,當virtualenv是而不是被激活時,依靠這個值是一個壞主意,因爲這是一個可以很容易地定製的Python的構建時間設置,並且它在一定的平臺之間肯定會有所不同。

然而,Python做有一個輕微運行差時,它從一個的virtualenv前綴與它的編譯的前綴運行:所述sys包具有附加的變量real_prefix返回其被編譯到Python二進制的前綴。因此,人們可以用它來識別Python,在非默認位置,這是相當有可能運行意味着它從運行的virtualenv:

import sys 

if getattr(sys, "real_prefix", None) is not None: 
    print "Maybe in a virtualenv" 
else: 
    print "Probably not in a virtualenv" 

然而,即使這不是一個精確的科學。所有這一切都告訴你,python二進制文件不在編譯時指定的位置。它不會告訴你當前用戶是否有權訪問寫入/usr/share/man - 有一些(可能是邊緣)情況下,這不會給你正確的答案:

  • 如果用戶已經編寫了他自己從他的家目錄及其編譯前綴源Python是/home/johnd/local-python然後real_prefix不會設置,但用戶仍然有寫權限的Python他目錄lib,並且可能寫訪問/etc/usr/share/man

  • 同樣,在管理員可能擁有的某些系統上將/usr/lib/python2.7的組寫權限授予某組應用開發人員,以便他們可以安裝Python模塊,但不授予他們對其他系統文件的寫權限。

所以我覺得你到底能做的最好的是啓發式的,它可能會更好,而不是僅僅避免data_files使用絕對路徑,你期望的virtualenv內使用任何模塊。妥協可能是簡單地將你的模塊分成兩個發行版,一個代表可本地化的源文件,另一個代表系統範圍的配置以使其運行。後者可以依靠前者,以便用戶仍然可以輕鬆安裝,但使用virtualenv的用戶可以直接使用其他前者。

相關問題