Как избежать неопределенного имени '_' F821 flake8, когда _ было установлено gettext?

Обзор проблемы:

В основном скрипте моего проекта gettext устанавливает функцию _(), которая используется в других модулях для переводов (например, в print(_('Something to translate'))).

Как указано в документе:

функция _() [установлена] в пространстве имен встроенных функций Python, поэтому она легко доступна во всех модулях вашего приложения.

Итак, все работает нормально.

Единственная проблема: 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.

Решения для решения ситуации, которые выглядят плохо (или хуже):

  • добавьте комментарий # noqa в конце каждой строки, используя _()
  • --ignore F821 (не хочу этого делать, потому что это полезно в других ситуациях)

person zezollo    schedule 15.06.2016    source источник
comment
Если вы не возражаете против аргументов, вы можете указать --builtins="_", что является более конкретным, чем --ignore F821.   -  person Anonymous    schedule 15.06.2016
comment
Ну да, это эффективно решает проблему. Вы можете опубликовать это как ответ.   -  person zezollo    schedule 15.06.2016
comment
Классический хорошо изученный вопрос, получив краткий и эффективный ответ (который имел непосредственное отношение к моим потребностям).   -  person BobHy    schedule 24.04.2020
comment
@BobHy Я должен уточнить, что после того, как я столкнулся со странными проблемами в других местах (pytest и doctests), непосредственно вызванными этим использованием _ в качестве ярлыка перевода, я наконец решил отказаться от этого. Я заменил _ на tr и импортирую его в любое время, как и для любого другого модуля.   -  person zezollo    schedule 25.04.2020


Ответы (1)


Вы можете указать --builtins="_", который является более конкретным, чем --ignore F821.

Вы также должны иметь возможность указать это в файле конфигурации, если вам не нравятся аргументы командной строки.

person Anonymous    schedule 15.06.2016
comment
Большое спасибо за эту точность в отношении файла конфигурации! Для плагина atom linter-flake8 пока нет настроек, но действительно возможно добавить строку builtins = _ в конфигурационный файл flake8, используемый для проекта (что переопределяет настройки, определенные в atom). - person zezollo; 15.06.2016
comment
Я должен уточнить, что после того, как я столкнулся со странными проблемами в других местах (pytest и doctests), непосредственно вызванными этим использованием _ в качестве ярлыка перевода, я наконец решил отказаться от этого. Я заменил _ на tr и импортирую его в любое время, как и для любого другого модуля. - person zezollo; 25.04.2020