我使用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)
答案 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