2017-06-01 69 views
4

我正在開發一個Python應用程序,並在分支發佈的過程中。我已經在公司服務器上設置了PyPI服務器,並且已將我的包的源代碼發佈複製到它上面。我應該如何處理在我的setup.py腳本中導入第三方庫?

我檢查到包裹在服務器上,然後嘗試在我的本地開發機器上安裝它。我結束了這樣的輸出:

$ pip3 install --trusted-host 172.16.1.92 -i http://172.16.1.92:5001/simple/ <my-package> 
Collecting <my-package> 
    Downloading http://172.16.1.92:5001/packages/<my-package>-0.2.0.zip 
    Complete output from command python setup.py egg_info: 
    Traceback (most recent call last): 
     File "<string>", line 1, in <module> 
     File "C:\Users\<me>\AppData\Local\Temp\pip-build-ubb3jkpr\<my-package>\setup.py", line 9, in <module> 
     import appdirs 
    ModuleNotFoundError: No module named 'appdirs' 

    ---------------------------------------- 
Command "python setup.py egg_info" failed with error code 1 in C:\Users\<me>\AppData\Local\Temp\pip-build-ubb3jkpr\<my-package>\ 

的原因是,我試圖導入第三方庫appdirs在我setup.py,這是必要的,我計算data_files參數setup()

try: 
    from setuptools import setup 
except ImportError: 
    from distutils.core import setup 

import os 
from collections import defaultdict 

import appdirs 
from <my-package>.version import __version__ as <my-package>_version 

APP_NAME = '<my-app>' 
APP_AUTHOR = '<company>' 
SYSTEM_COMPONENT_PLUGIN_DIR = os.path.join(appdirs.user_data_dir(APP_NAME, APP_AUTHOR), 'components') 

# ... 

setup(
    # ... 
    data_files=component_files, 
) 

但是,我沒有appdirs安裝在我的本地開發機器上,我不希望最終用戶也有它。

setup.py中依賴像這樣的第三方庫是否可以接受,如果有的話,推薦使用它們的方法是什麼?有沒有一種方法可以確保appdirs在導入setup.py之前得到安裝,或者我應該只是說明appdirs是安裝我的軟件包所需的軟件包?

+0

您是否嘗試過使用'setup_requires'?見https://pip.readthedocs.io/en/1.4.1/cookbook.html#controlling-setup-requires –

+0

@PeterBrittain有沒有任何如何使用它的例子?我應該做些什麼,比如做兩個'setup()'調用,一個靠近'setup.py'的頂部,只有'setup_requires = ['appdirs']'和我已經在底部的那個? – Tagc

+0

這並不常見......你可以在https://stackoverflow.com/questions/37471313/setup-requires-with-cython找到一個簡單的例子。這開始顯示了https://www.python.org/dev/peps/pep-0518/中提到的各種各樣的箍環,它突出顯示了另一個選項,即使用即將可用的pip來執行此操作。 –

回答

2

我忽略了此答案中的許可問題。您確實需要在實際發佈前考慮這些因素。

是否可以接受依靠第三方庫像這樣setup.py

是的,這是可以接受的,但通常這些應儘量減少,特別是如果這些是沒有明顯的使用的模塊爲最終用戶。沒有人喜歡擁有他們不需要或使用的軟件包。

什麼是使用它們的推薦方法?

基本上有3種選擇:

  • 引導他們(例如使用pip以編程方式安裝軟件包)。例如setuptools provides an ez_setup.py file可用於引導setuptools。也許可以自定義下載並安裝appdirs

  • 在項目中包含它們(特別是如果它是一個小包裝)。例如appdirs基本上只是一個單一的文件模塊。在您的項目中很容易複製和維護。當你這樣做的時候要特別小心許可問題!

  • 當不能導入它們並讓用戶安裝它們時,會失敗。例如:

    try: 
        import appdirs 
    except ImportError: 
        raise ImportError('this package requires "appdirs" to be installed. ' 
             'Install it first: "pip install appdirs".') 
    
+0

看起來'appdirs'是根據麻省理工學院頒發的許可證,所以在第三種情況下,第二種選擇似乎最具吸引力。理想情況下'setup_requires'(@PeterBrittain建議)看起來是最好的解決方案,但我不確定如何使用它。 – Tagc

+0

那麼,它取決於許可證,大小,穩定性以及是否還需要它作爲運行時依賴性來決定哪種方法是「最具吸引力」的。我個人不喜歡'setup_requires',因爲用一些本地安裝包(我認爲是'python setup.py install','python setup.py develop'或'pip install .'沒有工作)。 – MSeifert

+0

'appdirs'似乎可以在作爲本地模塊運行時很奇怪地解決路徑,所以我選擇了第三種選擇。 – Tagc

1

可以提與依存列表install_requires。請檢查python包裝指南here。你也可以提供一個要求。txt文件,以便它可以一次使用運行「PIP安裝-r」

+0

我不確定'install_requires'會如何幫助,你的意思是['setup_requires'](http://setuptools.readthedocs.io/en/latest/setuptools.html#new-and-changed-setup-keywords) ?不過,以我的經驗來說,要正確地做到這一點很困難。特別是如果不能提供'setuptools'安裝,並且給出'try:from setuptools import setup',這是不允許的。 – MSeifert

+0

如果沒有錯,setup_requires只是下載依賴關係,但install_requires安裝它們,我同意設置工具應該被導入。 – Venu

+0

@Venu:要求'setuptools'能夠安裝你的軟件包是很好的。如果你使用'pip'安裝,'setuptools'已經捆綁了。我只是在這裏使用'setuptools'和'setup_requires'。 –

0

你可以使用pip以編程方式安裝的軟件包,如果import失敗:

try: 
    import appdirs 
except ImportError: 
    import pip 
    pip.main(['install', 'appdirs']) 
    import appdirs 

在您可能需要使用某些情況下, importlib__import__pip.main之後導入包裹或重新填寫PATH變量。如果用戶真的想在安裝之前安裝該軟件包,那麼包含驗證也是值得的。

我使用了很多來自"Installing python module within code"的例子,我沒有親自嘗試在setup.py文件中使用過這個,但它看起來可能是您的問題的解決方案。