带有用户包的 py2app

py2app with user packages

我正在做一个小的跨平台 python 项目。我想将文件扩展名与程序相关联,因此对于 OSX 脚本似乎必须成为一个应用程序。 py2app 似乎是完成这项工作的完美工具,但我很难找到关于它的好文档。

我的 python 脚本依赖于我编写的包 (k.tk) 并符号链接到 /Library/Python/2.7/site-packages/k/tk(单个文件被符号链接到文件夹中 - 该文件夹不是符号链接) .

这是我正在使用的 setup.py 脚本:

"""
This is a setup.py script generated by py2applet

Usage:
    python setup.py py2app
"""

from setuptools import setup
import sys

APP = ['randomizer.py']
DATA_FILES = []
OPTIONS = {'argv_emulation': True, 'includes': ['k.tk']}

setup(
    app=APP,
    data_files=DATA_FILES,
    options={'py2app': OPTIONS},
    setup_requires=['py2app']
)

我的设置有两个问题,我都找到了一个我不喜欢的非常丑陋的解决方法。

第一个问题 - 别名构建

第一个问题出现在使用 python setup.py py2app -A 构建时。这应该构建带有源文件链接的应用程序,以使开发更容易。但是,当我尝试 运行 结果应用程序时,它显示

Import Error: No module named k.tk

解决方法是将这些行附加到 python 脚本:

import sys
sys.path.append("/Library/Python/2.7/site-packages/")

这似乎意味着从应用程序调用时 python 环境出现了问题,但我对 py2app 的了解还不够,不知道如何修复它。

第二个问题 - 完整构建

第二个问题发生在使用 python setup.py py2app 构建时。这会触发常规构建并将所有库复制到应用程序中。当我 运行 这个应用程序时,我得到

OSError: [Errno 20] Not a directory: '[path snipped]/application.app/Contents/Resources/lib/python2.7/site-packages.zip/k'

这里丑陋的解决方法是打开应用程序的文件并将 site-packages.zip 提取到名为 site-packages.zip 的文件夹中。现在错误消息中给出的路径是一个目录,应用程序 运行 没问题。

有谁知道如何解决这个问题?我感到很困惑,我能找到的唯一文档是 this,它似乎非常有限。

更新

我尝试将 /Library/Python/2.7/site-packages/k 目录复制到项目目录中。这修复了别名构建,但不幸的是不是完整构建。

我也尝试按照 Python 文档 (here) 中的说明正确打包和安装。这具有相同的效果。我感到很沮丧;为什么它会尝试将 zip 文件视为文件夹?

更新

我最终编写了一个构建脚本,它只是用同名目录覆盖了 zip。这解决了问题,但我对解决方案不满意。

我也开始尝试使用 py2exe 为 Windows 构建。在 Windows,我遇到了完全相同的问题!这次创建library.zip,必须提取程序才能运行。当然,这些程序不会碰巧有完全相同的错误,但我无法想象为什么它们都错误地期望 zip 文件可以像文件夹一样访问。

py2app 需要单独的 Python 安装而不是系统 Python 才能使捆绑包工作(我建议 HomeBrew)。如果 k.tk 是一个包含更多模块的软件包,您也可以尝试 packages 而不是 includes

如果由于某种原因上述解决方案不起作用,请尝试添加一些由 open(*, 'r')

打开的第 3 方包打开的 const 文件

将他们想要打开的添加到data_files=[..]