在安装时复制配置文件 [英] Copy configuration file on installation
问题描述
我正在尝试打包我的Python项目,该项目带有一个配置点文件,我想在安装时将其复制到用户的主目录中.打包快速指南指出,可以使用setuptools.setup
的data_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.
首先,我已将点文件放在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
目录,请参见
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
不幸的是,必须使用附加键(通过自述文件,网页FAQ或类似方式)分别告知用户有关使用附加键调用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屋!