Better i18n with gettext: use class-based API
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 5/5
- Tiempo estimado
- Más de una semana
- Aptitud para principiantes
- 35/100
- Tipo de issue
- Nueva funcionalidad
- Claridad
- Bastante claro
- Estado de actividad
- Estancado
- Stack tecnológico
- python
- Área
- cli, internationalization, localization
Línea de trabajo
Comienza localizando los usos actuales de from gettext import _ en Click y sus rutas de inicialización de comandos y grupos. Revisa después las APIs clásica y basada en clases de gettext de Python y define la cobertura de compatibilidad para la API antigua y la integración propuesta de click.i18n. Se considera terminado cuando Click ya no cambia el dominio global de gettext al importarse y los consumidores pueden separar los dominios de traducción.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Hi lovely Click maintainers,
Currently, Click implements gettext using the classic GNU gettext API. That looks like this:
from gettext import _
print(_("Hello, world!"))
This API depends on a global state in the gettext module. By calling gettext.textdomain(), the active translation domain is changed for all Python modules that use the classic GNU gettext API.
This side effect is usually desirable, except when your module is imported by another module as a library. So you usually don't want to call gettext.textdomain() without putting it behind some sort of function call. With argparse, this is easy: put it in your main function before you even create the ArgumentParser object. With Click, I'm not sure this is possible:
- Your main group/command is decorated with all manner of Click magic and its contents may not actually be run (e.g.
--help). - There is no way to pre-hook a group/command with a function call that I am aware of.
So you end up having to call gettext.textdomain() on import of your module containing your Click groups/commands.
We can fix that by switching to the class-based API. Because Click will still need to support the old API as well for backwards compatibility, my proposal looks a little as follows. Create a module click.i18n with the following contents (simplified):
import gettext as _gettext_module
TRANSLATIONS = None
def gettext(message):
if TRANSLATIONS is None:
return _gettext_module.gettext(message)
return TRANSLATIONS.gettext(message)
# alias
_ = gettext
Now, elsewhere in Click, you replace all from gettext import _ with from .i18n import _.
Subsequently, we can create a function install_translations(translations) in i18n.py that replaces the TRANSLATIONS global constant with an instantiated GNUTranslations object. This function would still need to be called before the consumer's main function, but it wouldn't change the gettext global state—it would only change Click's. Which, as far perfectionism goes, is probably tolerable. It would be better still if there was a pre-hook, but this is fine.
Furthermore, the consumer could use different domains for Click's TRANSLATIONS object and their own, allowing them to separate their own translations from Click's, and hypothetically reuse the Click translations in other projects.
In fact, having done this plumbing, Click could even ship its own translation strings, getting rid of duplication efforts of translating the same Click strings. Click's own translations could then be activated using e.g. install_click_translations() without any arguments.
In summary, the problems solved by this:
- Importing the Click consumer's module no longer changes the global state of the gettext module.
- Users can separate their own module's translations from Click's.
- Click would be enabled to provide its own translations to reduce duplication of efforts.
I am not aware of other ways to achieve the above that do not require changes to Click. Adding a pre-hook to groups/commands might partially address the problem.
I am willing to make a PR if this issue is validated.
I wrote a blog post here that provides more context on how I use gettext + Click (+ some other components). It has more context than is necessary to understand this issue.
- Lenguaje dominante
- Python
- Estrellas
- 17.8k
- Forks
- 3.3k
- Merge medio
- 3 d 3 h
- PR fusionados (30 d)
- 13
Preparar el entorno
Inicia el contenedor de desarrollo del proyecto en tu navegador, con tu propia cuenta de GitHub.
- Sin Dockerfile ni archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de pallets/click
-
`show_envvar=True` Drops Environment Variable from Error Messages When Using `auto_envvar_prefix`Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 66/100
Los mantenedores suelen responder en 1 día
-
More private utilities that need to be marked and public api deprecatedQuizá libre de nuevo Un pull request para esta issue se cerró sin fusionarse. Abiertotyping
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
pallets/click#3847 · 9 comentarios ·
Los mantenedores suelen responder en 1 día
-
Automatically append ellipsis (`...`) to metavars when `multiple=True` in optionsPosiblemente ocupada @SparshGarg999 la tomó hace 89 días. Abiertohelp output
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
pallets/click#3652 · 4 comentarios ·
Los mantenedores suelen responder en 1 día
-
`HelpFormatter.write_usage` breaks options at a hyphenPosiblemente ocupada @kdeldycke la tomó hace 9 días. Abiertohelp output
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
pallets/click#3362 · 4 comentarios ·
Los mantenedores suelen responder en 1 día
-
Add glossary of terms to click reference docsPosiblemente ocupada @rohitbarhate111-commits la tomó hace 55 días. Abiertodocs
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
pallets/click#3077 · 5 comentarios ·
Los mantenedores suelen responder en 1 día
Todos los issues de pallets/click
Issues similares
-
needs-triage
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
gke-labs/kube-agents#5671 ·
Los mantenedores suelen responder en 1 día
-
docs(auth): Method B step 4 should tell users to tick "Use this client for an AI-powered agent"Abiertodocumentation next-release v0.9.6
Dificultad 1/5 Menos de una hora Aptitud para principiantes 88/100
khuisman/mcp-gee-sweet#1446 ·
Los mantenedores suelen responder en 1 día
-
In-box secret files written before their chmod: lc-creds, stacks tee, and the workspace tokenAbiertomodel:sonnet runtime:claude security size:S
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
FootprintAI/Containarium#3671 ·
Los mantenedores suelen responder en 1 día
-
HolidayBase: reassigning `language` does not re-initialize translations or re-populate holidaysPosiblemente ocupada @shikhabhadoria la tomó hoy. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
vacanza/holidays#4116 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
bug CLI exec
Dificultad 2/5 1-3 horas Aptitud para principiantes 84/100
Los mantenedores suelen responder en 1 día