0

我有一个非常简单的 Python 程序,它使用“Blessed”。在Win10 Python解释器下运行良好,但与Pyinstaller打包时报错,终端控制代码被忽略。这是代码:

from blessed import Terminal
t = Terminal()
print(t.bright_green('Hello world'))

字符串“Hello world”应该以亮绿色显示在控制台上。Pyinstaller 完成时没有错误,当我运行 .exe 时,我收到以下消息:

terminal.py:222: UserWarning: 无法设置term(kind='vtwin10'): 找不到终端vtwin10

然后以默认终端颜色显示“Hello world”。

看起来 Pyinstaller 没有在构建中包含解释器发现没有问题的东西。我在我的 Anaconda3 安装文件夹中找到了一个 vtwin10.py 文件:

C:\Anaconda3\Lib\site-packages\jinxed\terminfo

我查看了祝福库的 terminal.py 文件中的引用错误。这是代码:

            try:
                curses.setupterm(self._kind, self._init_descriptor)
            except curses.error as err:
                warnings.warn('Failed to setupterm(kind={0!r}): {1}'
                              .format(self._kind, err))

所以看起来 self._kind 被设置为'vtwin10'。在 terminal.py 中有一个条件导入,如下所示:

if platform.system() == 'Windows':
    import jinxed as curses  # pylint: disable=import-error
    HAS_TTY = True

(我明白了。)看起来 jinxed 包正在代码中显式导入,并替换了 curses 包。但不知何故,缺少 vtwin10 定义。

我在 jinxed 中找到了 setupterm() 并深入挖掘以找到该错误消息的来源。它在这段代码中:

        try:
            self.terminfo = importlib.import_module('jinxed.terminfo.%s' % term.replace('-', '_'))
        except ImportError:
            raise error('Could not find terminal %s' % term)

这就是我卡住的地方。看起来此代码无法在 jinxed 库中找到 vtwin10.py 文件。有谁知道如何强制 Pyinstaller 包含诅咒的 vtwin10 终端定义?我猜这就是问题所在。

非常感谢。

4

2 回答 2

1

现在您只需要在 Windows 上指定jinxed.terminfo.vtwin10jinxed.terminfo.ansicon,但如果您希望它更加动态,pyinstaller 规范文件是可执行的 Python,因此您可以动态查找任何 terminfo 模块。

import pkgutil
import jinxed.terminfo
hiddenimports = [mod.name for mod in pkgutil.iter_modules(jinxed.terminfo.__path__, 'jinxed.terminfo.')
于 2020-01-12T06:14:45.693 回答
0

终于想通了。在 jinxed 库中,代码行:

importlib.import_module('jinxed.terminfo.%s' % term.replace('-', '_'))

动态加载库模块。Pyinstaller 无法打包动态导入的模块。所以要解决这个问题,我需要使用 --hidden-import 选项指定模块。语法如下:

pyinstaller --hidden-import=jinxed.terminfo.vtwin10 --onefile test.py

程序就像在解释器中一样工作。它有效,但我担心这会破坏任何平台独立性jinxed。我可以强制导入vtwin10.py模块,它可以在win10平台上运行。但是方式jinxed是写出来的,是先搞清楚windows平台,然后动态加载需要的terminfo模块。目录中有很多jinxed.terminfo。通配符--hidden-import不起作用,因此唯一的选择是--hidden-import用于文件夹中的每个文件jinxed.terminfo

于 2019-11-25T03:22:39.013 回答