安装时复制配置文件 [英] Copy configuration file on installation

查看:26
本文介绍了安装时复制配置文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试打包我的 Python 项目,该项目带有一个配置点文件,我想在安装时将其复制到用户的主目录中.打包的快速指南说这可以使用 setuptools.setupdata_files 参数来完成.所以这就是我所拥有的:

I am trying to package my Python project, which comes with a configuration dotfile that I want copied into the user's home directory on installation. The quick guide to packaging says that this can be done using the data_files argument to setuptools.setup. So this is what I have:

data_files = [(os.path.expanduser("~"), [".my_config"])]

如果我使用 python setup.py install,这似乎工作正常,但是当我将我的包上传到 PyPI 并运行 pip install 时,点文件没有被复制.

This appears to work fine if I use python setup.py install, but when I upload my package to PyPI and run pip install the dotfile isn't copied.

FWIW,我已将点文件放在 MANIFEST.in 中,并尝试将 package_data 参数包含到 setup 中.这些步骤似乎没有任何区别.如果我 pip install 并查看 site-packages 目录,那么这里只有源文件.

FWIW, I've put the dotfile in the MANIFEST.in and also tried including the package_data argument to setup. None of these steps appear to make a difference. If I pip install and poke around the site-packages directory, just the source files are here.

我怎样才能实现我的目标?

How can I achieve what I'm looking for?

推荐答案

这是我曾经亲身经历过的一个问题.其根源在于,在构建wheel文件时,data_files中指定的所有绝对路径都会相对于目标site-packages目录,见github 上的这个问题.这会影响 pip install 执行的安装,因为它会从任何源包(.tar.gz.tar.bz2.zip) 并安装生成的轮子:

This is an issue I had once to experience myself. Its root is that when you are building a wheel file, all the absolute paths specified in data_files will be relativized to the target site-packages directory, see this issue on github. This influences installations performed by pip install as it will build a wheel out of any source package (.tar.gz, .tar.bz2 or .zip) and install the resulting wheel:

$ pip install spam-0.1.tar.gz 
Processing ./spam-0.1.tar.gz
Building wheels for collected packages: spam
  Running setup.py bdist_wheel for spam ... done
  Stored in directory: /Users/hoefling/Library/Caches/pip/wheels/d0/95/be/bc79f1d589d90d67139481a3e706bcc54578fdbf891aef75c0
Successfully built spam
Installing collected packages: spam
Successfully installed spam-0.1

检查已安装的文件收益:

Checking installed files yields:

$ pip show -f spam
Name: spam
Version: 0.1
...
Location: /Users/hoefling/.virtualenvs/stackoverflow/lib/python3.6/site-packages
Requires: 
Files:
  Users/hoefling/.my_config
  spam-0.1.dist-info/DESCRIPTION.rst
  spam-0.1.dist-info/INSTALLER
  spam-0.1.dist-info/METADATA
  spam-0.1.dist-info/RECORD
  spam-0.1.dist-info/WHEEL
  spam-0.1.dist-info/metadata.json
  spam-0.1.dist-info/top_level.txt

请注意,绝对路径是相对于 Location 目录的.在示例中,.my_config 将放置在 /Users/hoefling/.virtualenvs/stackoverflow/lib/python3.6/site-packages/Users/hoefling/.my_config 下.

Note the path meant to be absolute is relative to the Location dir. In the example, .my_config would be placed under /Users/hoefling/.virtualenvs/stackoverflow/lib/python3.6/site-packages/Users/hoefling/.my_config.

它变得更好,因为这些构建的轮子缓存在你的磁盘上,所以下次你重新安装包并且构建的轮子仍然存在于pip的缓存中,它将用于安装你甚至不会在终端日志中看到任何关于构建轮子的提及.

It gets even better because these built wheels are cached on your disk, so next time you reinstall the package and the built wheel still exists in pip's cache, it will be used for the installation and you won't even see any mentions of building a wheel in the terminal log.

没有真正的解决方案可以避免这种情况.我发现的最体面的解决方法是在安装时禁止二进制"包以在安装时强制执行包的 setup.py:

There is no real solution to avoid this. The most decent workaround I found is to prohibit "binary" packages when installing to enforce the execution of package's setup.py on installation:

$ pip install spam-0.1.tar.gz --no-binary=spam
Processing ./spam-0.1.tar.gz
Skipping bdist_wheel for spam, due to binaries being disabled for it.
Installing collected packages: spam
  Running setup.py install for spam ... done
Successfully installed spam-0.1

文件现在已正确放置:

$ pip show -f spam
Name: spam
Version: 0.1
...
Location: /Users/hoefling/.virtualenvs/stackoverflow/lib/python3.6/site-packages
Requires: 
Files:
  ../../../../../.my_config
  spam-0.1-py3.6.egg-info/PKG-INFO
  spam-0.1-py3.6.egg-info/SOURCES.txt
  spam-0.1-py3.6.egg-info/dependency_links.txt
  spam-0.1-py3.6.egg-info/top_level.txt

遗憾的是,必须单独通知用户有关使用额外密钥调用 pip install 的信息(通过自述文件、网页常见问题或类似方式),因为不可能禁止在包元数据中构建轮子.

Unfortunately, the user must be separately informed about calling pip install with the extra key (via readme, webpage FAQ or similar) as there is no possibility to prohibit building the wheel in package metadata.

结果,我不再包含具有绝对路径的文件.相反,我将它们与 site-packages 目录中的 python 源代码一起安装.在 python 代码中,如有必要,我必须为存在检查和文件复制添加额外的逻辑:

As the result, I do not include files with absolute paths anymore. Instead, I install them with the python sources in the site-packages dir. In the python code, I have to add additional logic for the existence checks and file copying if necessary:

# program entrypoint

if __name__ == '__main__':
    config = os.path.join(os.path.expanduser('~'), '.my_config')
    if not os.path.exists(config):
        shutil.copyfile('.my_config', config)
    main.run()

这篇关于安装时复制配置文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆