Pular para conteúdo

Extração

A extração é a etapa que coleta todas as mensagens marcadas do seu código-fonte em um template .pot para quem traduz — o passo 3 do ciclo do tutorial. Esta página é a referência dessa etapa: configuração, nomes de função personalizados, modo estrito para CI e as verificações que protegem seus catálogos depois disso.

A extração requer o extra babel:

python -m pip install "gettext-tstrings[babel]"

Fluxo de trabalho

Crie babel.cfg:

[gettext_tstrings: **.py]
encoding = utf-8

Use então os comandos Babel habituais:

pybabel extract -F babel.cfg -c "Translators:" -o locales/messages.pot .
pybabel init -i locales/messages.pot -d locales -l ja
pybabel compile -d locales

O init roda uma única vez por idioma; depois disso, o pybabel update incorpora cada template recém-extraído aos catálogos existentes. Esse ciclo recorrente — e o que suas entradas fuzzy significam para um release — é percorrido em Em produção.

O extrator também processa _(), gettext() e ngettext(). Um único mapeamento cobre código misto, incluindo tr(), ntr(), lazy_gettext() e lazy_pgettext().

Ative os comentários para quem traduz com -c

O pybabel extract só coleta comentários dirigidos a quem traduz quando você passa -c "Translators:", exatamente como faz com as chamadas gettext comuns. Sem essa opção a extração continua funcionando — os comentários simplesmente nunca chegam ao catálogo, onde são a alavanca de qualidade mais barata de todo o fluxo.

Nomes de função personalizados

[gettext_tstrings: **.py]
tr_functions = tr translate
ntr_functions = ntr
[[mappings]]
method = "gettext_tstrings"
pattern = "**.py"
tr_functions = ["tr", "translate"]
ntr_functions = ["ntr"]

Em INI, o valor é uma string separada por espaços ou vírgulas; TOML aceita uma lista. As opções cobrem as seis famílias de funções gettext.

-k não alcança uma t-string

Um helper como mytr(t"…") deve ser declarado nessas opções. O mecanismo --keyword do Babel não lê literais t-string: pybabel extract -k mytr os omite sem avisar.

Somente a ordem padrão de argumentos é aceita.

Tolerante localmente, estrito na CI

Por padrão, um arquivo ruim não encerra a execução:

  • Uma t-string que o extrator rejeita — acesso a atributo, uma expressão, um argumento errado — é reportada como aviso e ignorada.
  • Um arquivo que não pode ser analisado de jeito nenhum é isolado do mesmo modo.
  • E também um arquivo que só o tokenize recusa enquanto o ast aceita, no qual a passagem do próprio Babel abortaria.

Isso é conveniente enquanto você está editando e perigoso quando não está: uma mensagem ignorada fica simplesmente ausente do POT, então ela nunca é traduzida e nada avisa. Defina strict = true nas opções do mapeamento em todo lugar em que a extração não esteja sendo observada por uma pessoa:

[gettext_tstrings: **.py]
encoding = utf-8
strict = true
[[mappings]]
method = "gettext_tstrings"
pattern = "**.py"
strict = true

Cada aviso acima passa então a ser uma falha dura. Trate isto como a configuração de produção e o padrão como a configuração local.

Validação com as ferramentas existentes

Babel adiciona uma flag padrão:

#. gettext-tstrings
#: app.py:4
#, python-brace-format
msgid "Hello {name}"
msgstr ""

Uma tradução こんにちは {nombre} é detectada sem configuração:

$ msgfmt --check-format -o /dev/null locales/ja/LC_MESSAGES/messages.po
locales/ja/LC_MESSAGES/messages.po:25: a format specification for argument
'name' doesn't exist in 'msgstr'
msgfmt: found 1 fatal error

O Weblate documenta essa verificação como Python brace format, e as plataformas comerciais têm sua própria QA de marcadores baseada na mesma flag. O comportamento de cada plataforma é assunto dela; as duas ferramentas abaixo são as que foram verificadas aqui.

pybabel compile aplica o checker a cada mensagem marcada:

$ pybabel compile -d locales -l ja
error: locales/ja/LC_MESSAGES/messages.po:24: translation does not match the
source placeholders: {name} is missing; {nombre} is not in the source message
1 errors encountered.

Para plurais, o erro identifica a forma:

error: locales/ru/LC_MESSAGES/messages.po:31: msgstr[1]: translation does not
match the source placeholders: {n} is missing

pybabel compile ainda grava o .mo

O erro acima é reportado, o status de saída é 1 — e o catálogo inválido é compilado mesmo assim. Só esse status de saída pode impedir um pipeline de publicá-lo; O que o CI barra mostra o passo de build que faz isso.

As duas verificações não são redundantes: o verificador do pacote é mais estrito em pelo menos dois casos, validando chaves escapadas e cada forma de plural separadamente, onde o msgfmt pode aceitar o arquivo. Nomes ASCII permitem que todas as ferramentas participem; a biblioteca aceita qualquer str.isidentifier().

Templates e outras ferramentas

t-strings são sintaxe Python. Jinja2 ({% trans %}), Django e outros templates mantêm seus próprios extratores, alimentando o mesmo catálogo PO.

pygettext ainda não analisa t-strings. A especificação permite que outros extratores sigam a mesma convenção.