当 gettext 安装了 _ 时,如何避免 flake8 的 "F821 undefined name '_'"?

How to avoid flake8's "F821 undefined name '_'" when _ has been installed by gettext?

问题概述:

在我项目的主脚本中,gettext 安装了在其他模块中用于翻译的函数 _()(如 print(_('Something to translate')))。

the doc所述:

the _() function [is] installed in Python’s builtins namespace, so it is easily accessible in all modules of your application.

所以,一切正常。

只有问题flake8显示错误(实际上由PyFlakes返回):

$ flake8 *.py
lib.py:2:12: F821 undefined name '_'
main_script.py:8:7: F821 undefined name '_'

这是正常的,因为 _ 确实没有在 main_script.py 和 lib.py 中定义。

重现问题的简单结构:

.
├── lib.py
├── locale
│   └── de
│       └── LC_MESSAGES
│           ├── myapp.mo
│           └── myapp.po
└── main_script.py

其中 lib.py 包含此内容:

def fct(sentence):
    return _(sentence)

和main_script.py这个:

#!/usr/bin/env python3

import gettext

import lib

gettext.translation('myapp', 'locale', ['de']).install()
print(_('A sentence'))
print(lib.fct('A sentence'))

和myapp.po包含:

msgid ""
msgstr ""
"Project-Id-Version: myapp\n"

msgid "A sentence"
msgstr "Ein Satz"

(由poedit编译生成mo文件)

如上所述,主脚本确实有效:

$ ./main_script.py 
Ein Satz
Ein Satz

重要说明:我正在寻找一种解决方案,既适用于 gettext.install() 被称为 的脚本,也适用于 所有其他模块 不需要调用 gettext.install(). 否则结构可以更简单,因为从main_script.py调用_()就够了触发 F821.

解决看起来很糟糕(或更糟)的情况的解决方案:

您可以指定比 --ignore F821 更具体的 --builtins="_"

如果您不喜欢命令行参数,您也应该能够在配置文件中指定它。