如何将data_files安装到绝对路径?

时间:2016-11-14 12:19:26

标签: python pip

我使用pip和setuptools来安装软件包。 我想让pip将一些资源文件复制到/etc/my_package

我的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)

3 个答案:

答案 0 :(得分:4)

简短回答:使用pip install --no-binary :all:安装您的软件包。

我挣扎了一段时间,最终发现在二元轮和源分布之间处理data_files的方式有些奇怪/不一致。具体来说,轮子存在一个错误,它使data_files中的所有路径相对于安装位置(有关跟踪此问题的问题,请参阅https://github.com/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:

答案 1 :(得分:1)

似乎data_files不能支持绝对路径,如果要将config.yml放到../site_packages/my_package,它会在" / etc / my_package"之前添加sys.prefix。 ,请尝试:

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'])]
)

答案 2 :(得分:0)

我最后写了一个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() 函数,它在第一次运行时安装配置文件,而不是在安装过程中创建它:

export PATH: export PATH=$PATH:/opt/bin