55Localization utilities to find available language packs and packages with
66localization data.
77"""
8+
89from __future__ import annotations
910
1011import gettext
4041L10N_SCHEMA_NAME = "@jupyterlab/translation-extension:plugin"
4142PY37_OR_LOWER = sys .version_info [:2 ] <= (3 , 7 )
4243
44+ # Pseudo language locale for in-context translation
45+ PSEUDO_LANGUAGE = "ach_UG"
46+
4347_default_schema_context = "schema"
4448_default_settings_context = "settings"
4549_lab_i18n_config = "jupyter.lab.internationalization"
@@ -151,7 +155,9 @@ def is_valid_locale(locale_: str) -> bool:
151155 - Brazilian German: "de_BR"
152156 """
153157 # Add exception for Norwegian
154- if locale_ == "no_NO" :
158+ if locale_ in {
159+ "no_NO" ,
160+ }:
155161 return True
156162
157163 valid = False
@@ -183,8 +189,11 @@ def get_display_name(locale_: str, display_locale: str = DEFAULT_LOCALE) -> str:
183189 """
184190 locale_ = locale_ if is_valid_locale (locale_ ) else DEFAULT_LOCALE
185191 display_locale = display_locale if is_valid_locale (display_locale ) else DEFAULT_LOCALE
186- loc = babel .Locale .parse (locale_ )
187- display_name = loc .get_display_name (display_locale )
192+ try :
193+ loc = babel .Locale .parse (locale_ )
194+ display_name = loc .get_display_name (display_locale )
195+ except babel .UnknownLocaleError :
196+ display_name = display_locale
188197 if display_name :
189198 display_name = display_name [0 ].upper () + display_name [1 :]
190199 return display_name # type:ignore[return-value]
@@ -312,21 +321,38 @@ def get_language_packs(display_locale: str = DEFAULT_LOCALE) -> tuple[dict, str]
312321 else :
313322 invalid_locales .append (locale_ )
314323
315- display_locale = display_locale if display_locale in valid_locales else DEFAULT_LOCALE
324+ display_locale_ = display_locale if display_locale in valid_locales else DEFAULT_LOCALE
316325 locales = {
317326 DEFAULT_LOCALE : {
318- "displayName" : get_display_name (DEFAULT_LOCALE , display_locale ),
327+ "displayName" : (
328+ get_display_name (DEFAULT_LOCALE , display_locale_ )
329+ if display_locale != PSEUDO_LANGUAGE
330+ else "Default"
331+ ),
319332 "nativeName" : get_display_name (DEFAULT_LOCALE , DEFAULT_LOCALE ),
320333 }
321334 }
322335 for locale_ in valid_locales :
323336 locales [locale_ ] = {
324- "displayName" : get_display_name (locale_ , display_locale ),
337+ "displayName" : get_display_name (locale_ , display_locale_ ),
325338 "nativeName" : get_display_name (locale_ , locale_ ),
326339 }
327340
328341 if invalid_locales :
329- messages .append (f"The following locales are invalid: { invalid_locales } !" )
342+ if PSEUDO_LANGUAGE in invalid_locales :
343+ invalid_locales .remove (PSEUDO_LANGUAGE )
344+ locales [PSEUDO_LANGUAGE ] = {
345+ "displayName" : "Pseudo-language" ,
346+ # Trick to ensure the proper language is selected in the language menu
347+ "nativeName" : (
348+ "to translate the UI"
349+ if display_locale != PSEUDO_LANGUAGE
350+ else "Pseudo-language"
351+ ),
352+ }
353+ # Check again as the pseudo-language was maybe the only invalid locale
354+ if invalid_locales :
355+ messages .append (f"The following locales are invalid: { invalid_locales } !" )
330356
331357 return locales , "\n " .join (messages )
332358
@@ -351,7 +377,11 @@ def get_language_pack(locale_: str) -> tuple:
351377 found_packages_locales , message = get_installed_packages_locale (locale_ )
352378 locale_data = {}
353379 messages = message .split ("\n " )
354- if not message and is_valid_locale (locale_ ) and locale_ in found_locales :
380+ if (
381+ not message
382+ and (locale_ == PSEUDO_LANGUAGE or is_valid_locale (locale_ ))
383+ and locale_ in found_locales
384+ ):
355385 path = found_locales [locale_ ]
356386 for root , __ , files in os .walk (path , topdown = False ):
357387 for name in files :
0 commit comments