setup.py:仅安装 pth 文件?
在创建一个自定义的 Python 版本时,最后一步我需要添加一个 myproject.pth
文件。
目前我是在一个 Makefile 里做这件事:
install:
rm -f ../../lib/python2.6/site-packages/myproject.pth
cp myproject.pth ../../lib/python2.6/site-packages/myproject.pth
但我想把这个过程放到一个 setup.py 文件里。可惜的是,setup.py 的文档似乎没有涉及到这个简单的情况!希望能得到一些帮助。我试过这样做,但没有成功:
from setuptools import setup
setup(
packages=['mypackage_pth'],
package_dir={'mypackage_pth': '.'},
package_data={'mypackage_pth': ['mypackage.pth']},
)
3 个回答
这段话是从stderr的回答中改编过来的。我不太确定这样做是否合适,但确实有效。
from distutils import sysconfig
site_packages_path = sysconfig.get_python_lib()
import shutil
shutil.copy('mypackage.pth', site_packages_path)
setup(...)
你需要找的是 data_files 这个参数,用来设置你的安装包:
from distutils import sysconfig
site_packages_path = sysconfig.get_python_lib()
setup(...,
data_files=[(site_packages_path, ["mypackage.pth"])]
)
在这里,正确的做法是扩展setuptools的build_py
,把源目录中的pth文件复制到构建目录中,也就是setuptools准备放入site-packages
的所有文件的位置。
from setuptools.command.build_py import build_py
class build_py_with_pth_file(build_py):
"""Include the .pth file for this project, in the generated wheel."""
def run(self):
super().run()
destination_in_wheel = "mypackage.pth"
location_in_source_tree = "src/mypackage.pth"
outfile = os.path.join(self.build_lib, destination_in_wheel)
self.copy_file(location_in_source_tree, outfile, preserve_mode=0)
setup(
...,
cmdclass={"build_py": build_py_with_pth_file},
)
在写这段话的时候,这里其他的答案都有一些微妙的错误。
data_files=[(site_packages_path, ["mypackage.pth"])]
这在语义上是错误的——pth文件不是数据。它是代码,就像你项目中其他的.py
文件一样。更重要的是,这在功能上也是有问题的——虽然问题不太明显,但很重要。
这样做会把site_packages_path
嵌入到生成的包中。你最终会得到一个包含类似以下文件路径的包:
my_package-1.0.0.data/data/lib/python3.9/site-packages/mypackage.pth
这个包只适用于Python 3.9(因为路径就是这个),但它很容易被标记为py3
(也就是说,兼容所有Python版本)。
这很难被发现,因为你需要一个开发流程,能够在多个不同的Python版本上运行测试,使用生成的包。
shutil.copy('mypackage.pth', site_packages_path)
这……不好。
虽然它可以在不同的Python版本上工作,但即使用户只是下载了项目,使用pip download mypackage
,这个pth文件也会被“安装”。
更重要的是,为这个项目生成的包不会有任何与项目相关的pth文件。因此,后续的安装不会得到这个pth文件(因为pip会缓存本地构建的包)。
这无法通过在本地从源目录安装来重现,同样也不容易发现:你需要一个开发流程,在与构建环境不同的环境中安装这个包,以便以一种可以检测到的方式运行测试。