PyInstaller打包项目遇sys.stderr为None报错(transformers升级后)
解决Transformers 4.25.1 + PyInstaller编译时的sys.stderr NoneType错误
问题背景
将transformers库从4.16.0版本升级至4.25.1后,使用PyInstaller编译GUI项目(配置中console=False)时触发以下错误:
Traceback (most recent call last): File "main.py", line 14, in <module> ... File "transformers\utils\import_utils.py", line 36, in <module> File "transformers\utils\logging.py", line 123, in get_logger File "transformers\utils\logging.py", line 86, in _configure_library_root_logger AttributeError: 'NoneType' object has no attribute 'flush'
经排查,错误根源是transformers初始化日志时,sys.stderr被设置为NoneType,导致日志模块调用flush()方法失败。
解决方案
以下是三种无需降级transformers的解决方法:
1. 添加运行时钩子修复sys.stderr
创建名为fix_stderr.py的运行时钩子文件,内容如下:
import sys import os # 当sys.stderr为None时,重定向到空设备 if sys.stderr is None: sys.stderr = open(os.devnull, 'w')
修改PyInstaller的spec配置文件,在Analysis部分添加该钩子:
a = Analysis(['main.py'], # 其他参数保持不变 runtime_hooks=['fix_stderr.py'], # 其他参数保持不变)
2. 临时补丁transformers日志初始化逻辑
找到Python环境中transformers/utils/logging.py文件,修改_configure_library_root_logger函数,在使用sys.stderr前增加非空检查:
import sys import os import logging def _configure_library_root_logger(): logger = logging.getLogger("transformers") if logger.handlers: return logger # 处理sys.stderr为None的情况 stderr_stream = sys.stderr if sys.stderr is not None else open(os.devnull, 'w') formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") stream_handler = logging.StreamHandler(stderr_stream) stream_handler.setFormatter(formatter) logger.addHandler(stream_handler) logger.setLevel(logging.INFO) logger.propagate = False return logger
注意:该方法会修改库源码,若重新安装transformers需重新补丁。
3. 编译时启用控制台(妥协方案)
若项目允许弹出控制台窗口,可将spec文件中EXE部分的console=False改为console=True,这样sys.stderr会正常初始化,避免错误。
内容的提问来源于stack exchange,提问作者chiai-fuka
相关产品推荐
相关产品推荐

