setup.py:只安装一个pth文件?

Mar*_*son 8 python

作为构建自定义python的最后一步,我需要添加一个myproject.pth.

目前我在Makefile中这样做:

install:
        rm -f            ../../lib/python2.6/site-packages/myproject.pth
        cp myproject.pth ../../lib/python2.6/site-packages/myproject.pth
Run Code Online (Sandbox Code Playgroud)

但我想将其封装在setup.py中.不幸的是,setup.py文档似乎并没有涵盖这个简单的案例!任何帮助赞赏.我试过这个,但它不起作用:

from setuptools import setup
setup(
    packages=['mypackage_pth'],
    package_dir={'mypackage_pth': '.'},
    package_data={'mypackage_pth': ['mypackage.pth']},
)
Run Code Online (Sandbox Code Playgroud)

pra*_*nsg 10

这里正确的做法是扩展 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},
)
Run Code Online (Sandbox Code Playgroud)

这里的所有其他答案(在撰写本文时)都以微妙的方式错误。

data_files=[(site_packages_path, ["mypackage.pth"])]
Run Code Online (Sandbox Code Playgroud)

这在语义上是错误的——pth 文件不是数据。它是代码,就像.py项目其余部分中的各种文件是代码一样。更重要的是,这在功能上也被破坏了——以一种稍微微妙但重要的方式。

这将嵌入site_packages_path轮子中。您最终会得到一个包含文件路径的轮子,例如:

my_package-1.0.0.data/data/lib/python3.9/site-packages/mypackage.pth
Run Code Online (Sandbox Code Playgroud)

这个轮子仅适用于 Python 3.9(因为这就是路径),但它很容易标记为py3(即与所有 Python 版本兼容)。

检测起来并不简单,因为您需要一个开发工作流程,使用生成的轮子在多个不同的Python 版本上运行测试。

shutil.copy('mypackage.pth', site_packages_path)
Run Code Online (Sandbox Code Playgroud)

这不好。

虽然它可以跨 Python 版本运行,但即使用户下载了带有 .pth 文件的项目,这也会“安装”pth 文件pip download mypackage

更重要的是,为此项目生成的wheel将不会有任何与该项目关联的pth文件。因此,后续安装将不会安装 pth 文件(因为 pip 将缓存本地构建的轮子)。

这无法通过从本地源目录安装来重现,并且同样不简单:检测起来并不简单,因为您需要一个开发工作流程来将包安装在与您所安装的环境不同的环境中。构建它,以他们可以检测到这一点的方式运行测试。


std*_*err 5

您正在寻找设置的data_files参数:

from distutils import sysconfig
site_packages_path = sysconfig.get_python_lib()

setup(...,
  data_files=[(site_packages_path, ["mypackage.pth"])]
 )
Run Code Online (Sandbox Code Playgroud)

  • @MikeSteder,文件最终在 `d:/venv2/Lib/site-packages/foobar-2.0.SNAPSHOT-py2.5.egg/` 而不仅仅是 `d:/venv2/Lib/site-packages/`。 (2认同)