Add locale.getlocale()

This returns the localization of the running CircuitPython, such as
en_US, fr, etc.

Additional changes are needed in build infrastructure since the
string "en_US" should not appear to be translated in weblate, ever;
instead the value comes from the translation metadata.

Closes: #8602
This commit is contained in:
Jeff Epler 2023-11-14 11:27:42 -06:00
parent ed7c714fe2
commit 46bfbad1bb
No known key found for this signature in database
GPG Key ID: D5BF15AB975AB4DE
8 changed files with 82 additions and 3 deletions

View File

@ -227,7 +227,7 @@ pseudoxml:
all-source: all-source:
locale/circuitpython.pot: all-source locale/circuitpython.pot: all-source
find $(TRANSLATE_SOURCES) -type d \( $(TRANSLATE_SOURCES_EXC) \) -prune -o -type f \( -iname "*.c" -o -iname "*.h" \) -print | (LC_ALL=C sort) | xgettext -f- -L C -s --add-location=file --keyword=MP_ERROR_TEXT -o - | sed -e '/"POT-Creation-Date: /d' > $@ find $(TRANSLATE_SOURCES) -type d \( $(TRANSLATE_SOURCES_EXC) \) -prune -o -type f \( -iname "*.c" -o -iname "*.h" \) -print | (LC_ALL=C sort) | xgettext -x locale/synthetic.po -f- -L C -s --add-location=file --keyword=MP_ERROR_TEXT -o - | sed -e '/"POT-Creation-Date: /d' > $@
# Historically, `make translate` updated the .pot file and ran msgmerge. # Historically, `make translate` updated the .pot file and ran msgmerge.
# However, this was a frequent source of merge conflicts. Weblate can perform # However, this was a frequent source of merge conflicts. Weblate can perform

3
locale/synthetic.po Normal file
View File

@ -0,0 +1,3 @@
# Localization of the locale name is done automagically
msgid "en_US"
msgstr ""

View File

@ -33,6 +33,7 @@ SRC_BITMAP := \
shared-bindings/audiomixer/MixerVoice.c \ shared-bindings/audiomixer/MixerVoice.c \
shared-bindings/bitmaptools/__init__.c \ shared-bindings/bitmaptools/__init__.c \
shared-bindings/displayio/Bitmap.c \ shared-bindings/displayio/Bitmap.c \
shared-bindings/locale/__init__.c \
shared-bindings/rainbowio/__init__.c \ shared-bindings/rainbowio/__init__.c \
shared-bindings/struct/__init__.c \ shared-bindings/struct/__init__.c \
shared-bindings/synthio/__init__.c \ shared-bindings/synthio/__init__.c \
@ -82,6 +83,7 @@ CFLAGS += \
-DCIRCUITPY_DISPLAYIO_UNIX=1 \ -DCIRCUITPY_DISPLAYIO_UNIX=1 \
-DCIRCUITPY_FUTURE=1 \ -DCIRCUITPY_FUTURE=1 \
-DCIRCUITPY_GIFIO=1 \ -DCIRCUITPY_GIFIO=1 \
-DCIRCUITPY_LOCALE=1 \
-DCIRCUITPY_OS_GETENV=1 \ -DCIRCUITPY_OS_GETENV=1 \
-DCIRCUITPY_RAINBOWIO=1 \ -DCIRCUITPY_RAINBOWIO=1 \
-DCIRCUITPY_STRUCT=1 \ -DCIRCUITPY_STRUCT=1 \

View File

@ -239,6 +239,9 @@ endif
ifeq ($(CIRCUITPY_KEYPAD),1) ifeq ($(CIRCUITPY_KEYPAD),1)
SRC_PATTERNS += keypad/% SRC_PATTERNS += keypad/%
endif endif
ifeq ($(CIRCUITPY_LOCALE),1)
SRC_PATTERNS += locale/%
endif
ifeq ($(CIRCUITPY_MATH),1) ifeq ($(CIRCUITPY_MATH),1)
SRC_PATTERNS += math/% SRC_PATTERNS += math/%
endif endif
@ -544,6 +547,7 @@ $(filter $(SRC_PATTERNS), \
displayio/Colorspace.c \ displayio/Colorspace.c \
fontio/Glyph.c \ fontio/Glyph.c \
imagecapture/ParallelImageCapture.c \ imagecapture/ParallelImageCapture.c \
locale/__init__.c \
math/__init__.c \ math/__init__.c \
microcontroller/ResetReason.c \ microcontroller/ResetReason.c \
microcontroller/RunMode.c \ microcontroller/RunMode.c \

View File

@ -320,6 +320,9 @@ CFLAGS += -DCIRCUITPY_KEYPAD_KEYMATRIX=$(CIRCUITPY_KEYPAD_KEYMATRIX)
CIRCUITPY_KEYPAD_SHIFTREGISTERKEYS ?= $(CIRCUITPY_KEYPAD) CIRCUITPY_KEYPAD_SHIFTREGISTERKEYS ?= $(CIRCUITPY_KEYPAD)
CFLAGS += -DCIRCUITPY_KEYPAD_SHIFTREGISTERKEYS=$(CIRCUITPY_KEYPAD_SHIFTREGISTERKEYS) CFLAGS += -DCIRCUITPY_KEYPAD_SHIFTREGISTERKEYS=$(CIRCUITPY_KEYPAD_SHIFTREGISTERKEYS)
CIRCUITPY_LOCALE ?= $(CIRCUITPY_FULL_BUILD)
CFLAGS += -DCIRCUITPY_LOCALE=$(CIRCUITPY_LOCALE)
CIRCUITPY_MATH ?= 1 CIRCUITPY_MATH ?= 1
CFLAGS += -DCIRCUITPY_MATH=$(CIRCUITPY_MATH) CFLAGS += -DCIRCUITPY_MATH=$(CIRCUITPY_MATH)

View File

@ -92,7 +92,10 @@ def translate(translation_file, i18ns):
unescaped = original unescaped = original
for s in C_ESCAPES: for s in C_ESCAPES:
unescaped = unescaped.replace(C_ESCAPES[s], s) unescaped = unescaped.replace(C_ESCAPES[s], s)
translation = table.gettext(unescaped) if original == "en_US":
translation = table.info()["language"]
else:
translation = table.gettext(unescaped)
# Add in carriage returns to work in terminals # Add in carriage returns to work in terminals
translation = translation.replace("\n", "\r\n") translation = translation.replace("\n", "\r\n")
translations.append((original, translation)) translations.append((original, translation))

View File

@ -0,0 +1,62 @@
/*
* This file is part of the Micro Python project, http://micropython.org/
*
* The MIT License (MIT)
*
* SPDX-FileCopyrightText: Copyright (c) 2023 Jeff Epler for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "py/obj.h"
#include "py/objtuple.h"
//| def getlocale(path: str, times: Tuple[int, int]) -> None:
//| """Change the timestamp of a file."""
//| ...
//|
STATIC mp_obj_t getlocale(void) {
mp_rom_error_text_t locale_msg = MP_ERROR_TEXT("en_US");
size_t len_with_nul = decompress_length(locale_msg);
size_t len = len_with_nul - 1;
char buf[len_with_nul];
decompress(locale_msg, buf);
mp_obj_t elements[] = {
mp_obj_new_str(buf, len),
MP_OBJ_NEW_QSTR(MP_QSTR_utf_hyphen_8)
};
return mp_obj_new_tuple(MP_ARRAY_SIZE(elements), elements);
}
MP_DEFINE_CONST_FUN_OBJ_0(getlocale_obj, getlocale);
STATIC const mp_rom_map_elem_t locale_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_locale) },
{ MP_ROM_QSTR(MP_QSTR_getlocale), MP_ROM_PTR(&getlocale_obj) },
};
STATIC MP_DEFINE_CONST_DICT(locale_module_globals, locale_module_globals_table);
const mp_obj_module_t locale_module = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&locale_module_globals,
};
MP_REGISTER_MODULE(MP_QSTR_locale, locale_module);

View File

@ -13,8 +13,10 @@ import polib
template_filename = sys.argv[1] template_filename = sys.argv[1]
po_filenames = sys.argv[2:] po_filenames = sys.argv[2:]
synthetic = polib.pofile("locale/synthetic.po")
synthetic_ids = set([x.msgid for x in synthetic])
template = polib.pofile(template_filename) template = polib.pofile(template_filename)
all_ids = set([x.msgid for x in template]) all_ids = set([x.msgid for x in template]) - synthetic_ids
for po_filename in po_filenames: for po_filename in po_filenames:
print("Checking", po_filename) print("Checking", po_filename)
po_file = polib.pofile(po_filename) po_file = polib.pofile(po_filename)