安装时复制配置文件

Xop*_*ter 8 python pip setuptools

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

data_files = [(os.path.expanduser("~"), [".my_config"])]
Run Code Online (Sandbox Code Playgroud)

如果我使用python setup.py install,这似乎工作正常,但是当我将我的包上传到 PyPI 并运行时pip install,不会复制 dotfile。

FWIW,我已经把dotfile中MANIFEST.in,也尝试了包括package_data参数setup。这些步骤似乎没有任何区别。如果我pip install和闲逛的site-packages目录,就在源文件所在的位置。

我怎样才能实现我正在寻找的东西?

hoe*_*ing 9

这是我曾经亲身经历过的一个问题。其根源在于,在构建wheel文件时,中指定的所有绝对路径data_files都会相对于目标site-packages目录,请参阅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
Run Code Online (Sandbox Code Playgroud)

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

$ 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
Run Code Online (Sandbox Code Playgroud)

请注意,绝对路径是相对于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
Run Code Online (Sandbox Code Playgroud)

该文件现在已正确放置:

$ 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
Run Code Online (Sandbox Code Playgroud)

不幸的是,必须单独通知用户有关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()
Run Code Online (Sandbox Code Playgroud)