安装时复制配置文件

时间:2017-11-23 17:26:23

标签: python pip setuptools

我正在尝试打包我的Python项目,它带有一个配置点文件,我希望在安装时将其复制到用户的主目录中。包装的快速指南说明这可以使用data_files的{​​{1}}参数来完成。所以这就是我所拥有的:

setuptools.setup

如果我使用data_files = [(os.path.expanduser("~"), [".my_config"])] ,这似乎工作正常,但当我将我的包上传到PyPI并运行python setup.py install时,不会复制点文件。

FWIW,我已将dotfile放在pip install中,并尝试将MANIFEST.in参数包含在package_data中。这些步骤似乎没有任何区别。如果我setup并在pip install目录周围徘徊,那么源文件就在这里。

我如何实现我正在寻找的目标?

2 个答案:

答案 0 :(得分:2)

这是我曾经经历过的一个问题。它的根源在于,当您构建wheel文件时,data_files中指定的所有绝对路径将被相对化为目标site-packages目录,请参阅this issue on github。这会影响pip install执行的安装,因为它会从任何源包(.tar.gz.tar.bz2.zip)构建一个轮子并安装生成的轮子:

$ 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

检查已安装的文件会产生:

$ 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下。

它变得更好,因为这些构建的轮子缓存在磁盘上,因此下次重新安装软件包并且构建的轮子仍然存在于pip的缓存中时,它将用于安装而且你甚至没有看到任何在终端日志中建造轮子的提及。

没有真正的解决办法来避免这种情况。我发现最合适的解决方法是禁止二进制"安装时的软件包,以便在安装时强制执行软件包setup.py

$ 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,因为不可能禁止在包元数据中构建轮子。

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

# 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()

答案 1 :(得分:1)

除了@hoefling所说的,我建议您根本不要使用data_files!因为将文件复制到的位置确实不可预测。您可以通过给目录类似'''/''/anything/you/want'的方式进行测试。

我建议您改用package_data,它只是在安装时将文件复制到分布式软件包根目录下。然后,您可以在运行时将其复制到任何位置。

有关package_data的更多信息,请参阅Python Doc https://docs.python.org/2/distutils/setupscript.html#installing-package-data