2016-11-14 37 views
0

我使用pip和setuptools來安裝一個包。 我希望pip將一些資源文件複製到/etc/my_package如何將data_files安裝到絕對路徑?

setup.py看起來是這樣的:

setup(
    ... 
    data_files=[('/etc/my_package', ['config.yml'])] 
) 

當運行pip install,在該文件中

~/.local/lib/python3.5/site-packages/etc/my_package/config.yml 

,而不是/etc/my_package結束。

我在做什麼錯?

(PIP版本9.0.1)

回答

2

簡短回答:使用pip install --no-binary :all:安裝您的軟件包。

我掙扎了一會兒,最終發現在二進制輪子和源代碼分發之間如何處理data_files有一些奇怪/不一致。具體而言,輪子有一個缺陷,使所有路徑相對於安裝位置爲data_files(有關跟蹤此問題的問題,請參閱https://bitbucket.org/pypa/wheel/issues/92)。

「這很好」,你可能會說,「但我沒有使用輪子!」。沒那麼快!事實證明,最近版本的pip(我正在使用9.0.1)將嘗試從源代碼分發中編譯一個輪子。例如,如果你有一個包my_package你可以看到這個做這樣的事情

$ python setup.py sdist # create source tarball as dist/my_package.tar.gz 
       [...] 
$ pip install dist/my_package.tar.gz # install the generated source 
       [...] 
Building wheels for collected packages: my_package 
    Running setup.py bdist_wheel for my_package ... done 

pip嘗試是有益的,建立一個車輪從安裝和緩存供以後使用。這意味着即使理論上你自己並沒有使用bdist_wheel,也會遇到上述錯誤。您可以通過直接從軟件包源文件夾運行python setup.py install來解決此問題。這可以避免構建和緩存構建輪子pip將嘗試執行,但是當您想要的包已經在PyPI某處時很不方便。幸運的是pip提供了顯式禁用二進制文件的選項。

$ pip install --no-binary :all: my_package 
       [...] 
Skipping bdist_wheel for my_package, due to binaries being disabled for it. 
Installing collected packages: my_package 
    Running setup.py install for my_package ... done 
Successfully installed my_package-0.1.0 

使用--no-binary選項可以防止車輪建設,讓我們再次引用我們data_files路徑絕對路徑。對於要安裝大量包裝並希望選擇性禁用車輪的情況,您可以用逗號分隔的包列表替換:all:

0

我最後寫一個init()功能安裝在首次運行配置文件,而不是在安裝過程中創建它的:

def init(): 
    try: 
     if not path.isdir(config_dir): 
      os.mkdir(cs_dir) 
      copyfile(pkg_resources.resource_filename(
           __name__, "default_config.yml"), config_file) 
      print("INFO: config file created. ") 
    except IOError as ex: 
     print("ERROR: could not create config directory: " + str(ex) 

if __name__ == "__main__": 
    init() 
    main() 
1

似乎data_files能「T支持絕對路徑,它將之前在 「/ etc/my_package」 添加sys.prefix,如果你想要把config.yml到../site_packages/my_package,請嘗試:

import os 
import sys 
from distutils.sysconfig import get_python_lib 
relative_site_packages = get_python_lib().split(sys.prefix+os.sep)[1] 
date_files_relative_path = os.path.join(relative_site_packages, "my_package") 
setup(
... 
data_files=[(date_files_relative_path, ['config.yml'])] 
)