Skip to content

Commit bf57b0a

Browse files
committed
Use Babel's Locale everywhere to reduce data conversions
1 parent 609414c commit bf57b0a

File tree

95 files changed

+864
-803
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

95 files changed

+864
-803
lines changed

betty/ancestry/locale.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@
1313
LinkedDataDumpableWithSchemaJsonLdObject,
1414
)
1515
from betty.json.schema import Null, OneOf
16-
from betty.locale import UNDETERMINED_LOCALE
16+
from betty.locale import LocaleLike, ensure_locale, to_language_tag
1717
from betty.locale.localized import Localized
1818
from betty.locale.schema import LocaleSchema
1919
from betty.privacy import is_public
2020

2121
if TYPE_CHECKING:
22+
from babel import Locale
23+
2224
from betty.project import Project
2325
from betty.serde.dump import Dump, DumpMapping
2426

@@ -31,25 +33,25 @@ class HasLocale(Localized, LinkedDataDumpableWithSchemaJsonLdObject):
3133
def __init__(
3234
self,
3335
*args: Any,
34-
locale: str = UNDETERMINED_LOCALE,
36+
locale: LocaleLike | None = None,
3537
**kwargs: Any,
3638
):
3739
super().__init__(*args, **kwargs)
38-
self._locale = locale
40+
self._locale = None if locale is None else ensure_locale(locale)
3941

4042
@override # type: ignore[explicit-override]
4143
@property
42-
def locale(self) -> str:
44+
def locale(self) -> Locale | None:
4345
return self._locale
4446

4547
@locale.setter
46-
def locale(self, locale: str) -> None:
48+
def locale(self, locale: Locale | None) -> None:
4749
self._locale = locale
4850

4951
@override
5052
async def dump_linked_data(self, project: Project, /) -> DumpMapping[Dump]:
5153
dump = await super().dump_linked_data(project)
52-
dump["locale"] = self.locale if is_public(self) else None
54+
dump["locale"] = to_language_tag(self.locale) if is_public(self) else None
5355
return dump
5456

5557
@override

betty/ancestry/person_name.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
from betty.ancestry.locale import HasLocale
1313
from betty.json.linked_data import JsonLdObject, dump_context
1414
from betty.json.schema import String
15-
from betty.locale import UNDETERMINED_LOCALE
1615
from betty.locale.localizable import Localizable, _, ngettext
1716
from betty.model import Entity, EntityPlugin
1817
from betty.model.association import BidirectionalToOne, ToManyAssociates, ToOneAssociate
@@ -21,6 +20,7 @@
2120
if TYPE_CHECKING:
2221
from betty.ancestry.citation import Citation
2322
from betty.ancestry.person import Person
23+
from betty.locale import LocaleLike
2424
from betty.project import Project
2525
from betty.serde.dump import Dump, DumpMapping
2626

@@ -59,7 +59,7 @@ def __init__(
5959
privacy: Privacy | None = None,
6060
public: bool | None = None,
6161
private: bool | None = None,
62-
locale: str = UNDETERMINED_LOCALE,
62+
locale: LocaleLike | None = None,
6363
citations: ToManyAssociates[Citation] | None = None,
6464
):
6565
if not individual and not affiliation:

betty/app/config.py

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,14 @@
88

99
from typing_extensions import override
1010

11-
from betty.assertion import (
12-
OptionalField,
13-
assert_locale,
14-
assert_record,
15-
assert_setattr,
16-
assert_str,
17-
)
11+
from betty.assertion import OptionalField, assert_locale, assert_record, assert_setattr
1812
from betty.config import Configuration
1913
from betty.dirs import APP_CONFIG_DIRECTORY_PATH
14+
from betty.locale import to_language_tag
2015

2116
if TYPE_CHECKING:
17+
from babel import Locale
18+
2219
from betty.serde.dump import Dump, DumpMapping
2320

2421
CONFIGURATION_FILE_PATH = APP_CONFIG_DIRECTORY_PATH / "app.json"
@@ -33,32 +30,32 @@ class AppConfiguration(Configuration):
3330
def __init__(
3431
self,
3532
*,
36-
locale: str | None = None,
33+
locale: Locale | None = None,
3734
):
3835
super().__init__()
39-
self._locale: str | None = locale
36+
self._locale: Locale | None = locale
4037

4138
@property
42-
def locale(self) -> str | None:
39+
def locale(self) -> Locale | None:
4340
"""
4441
The application locale.
4542
"""
4643
return self._locale
4744

4845
@locale.setter
49-
def locale(self, locale: str) -> None:
46+
def locale(self, locale: Locale | None) -> None:
5047
self.assert_mutable()
51-
self._locale = assert_locale()(locale)
48+
self._locale = locale
5249

5350
@override
5451
def load(self, dump: Dump, /) -> None:
5552
self.assert_mutable()
5653
assert_record(
57-
OptionalField("locale", assert_str() | assert_setattr(self, "locale"))
54+
OptionalField("locale", assert_locale() | assert_setattr(self, "locale"))
5855
)(dump)
5956

6057
@override
6158
def dump(self) -> DumpMapping[Dump]:
6259
if self.locale is None:
6360
return {}
64-
return {"locale": self.locale}
61+
return {"locale": to_language_tag(self.locale)}

betty/assertion.py

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from pathlib import Path
1818
from types import NoneType
1919
from typing import (
20+
TYPE_CHECKING,
2021
Any,
2122
Generic,
2223
TypeAlias,
@@ -29,10 +30,13 @@
2930
from betty.data import Index, Key
3031
from betty.error import FileNotFound
3132
from betty.exception import HumanFacingException, HumanFacingExceptionGroup
32-
from betty.locale import UNDETERMINED_LOCALE, get_data
33+
from betty.locale import from_language_tag
3334
from betty.locale.localizable import Localizable, Paragraph, _, do_you_mean
3435
from betty.typing import Void, Voidable, internal
3536

37+
if TYPE_CHECKING:
38+
from babel import Locale
39+
3640
Number: TypeAlias = int | float
3741

3842

@@ -525,30 +529,11 @@ def _assert_file_path(file_path: Path, /) -> Path:
525529
return assert_path() | _assert_file_path
526530

527531

528-
def assert_locale() -> AssertionChain[Any, str]:
532+
def assert_locale() -> AssertionChain[Any, Locale]:
529533
"""
530534
Assert that a value is a valid `IETF BCP 47 language tag <https://en.wikipedia.org/wiki/IETF_language_tag>`_.
531535
"""
532-
533-
def _assert_locale(value: str, /) -> str:
534-
# Allow locales for which no system information usually exists.
535-
if value == UNDETERMINED_LOCALE:
536-
return value
537-
538-
try:
539-
get_data(value)
540-
except HumanFacingException as error:
541-
raise HumanFacingException(error) from error
542-
return value
543-
544-
return assert_locale_identifier() | _assert_locale
545-
546-
547-
def assert_locale_identifier() -> AssertionChain[Any, str]:
548-
"""
549-
Assert that a value could be a valid `IETF BCP 47 language tag <https://en.wikipedia.org/wiki/IETF_language_tag>`_.
550-
"""
551-
return assert_str() | assert_len(minimum=1) | str
536+
return assert_str() | from_language_tag
552537

553538

554539
def assert_setattr(instance: object, attr_name: str, /) -> AssertionChain[Any, Any]:

betty/assets/locale/ar/betty.po

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ msgid ""
77
msgstr ""
88
"Project-Id-Version: Betty VERSION\n"
99
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
10-
"POT-Creation-Date: 2025-11-25 02:03+0000\n"
10+
"POT-Creation-Date: 2025-11-27 01:37+0000\n"
1111
"PO-Revision-Date: 2024-11-30 19:00+0000\n"
1212
"Last-Translator: Bart Feenstra <[email protected]>\n"
1313
"Language: ar\n"
@@ -679,7 +679,7 @@ msgid "Locale aliases must not contain slashes."
679679
msgstr ""
680680

681681
#, python-brace-format
682-
msgid "Locale {locale} is not supported by your system."
682+
msgid "Locale {locale} is not known by your system."
683683
msgstr ""
684684

685685
msgid "Locality"
@@ -1205,11 +1205,11 @@ msgid "Unknown key: {unknown_key}."
12051205
msgstr ""
12061206

12071207
#, python-brace-format
1208-
msgid "Unknown locale {locale}."
1208+
msgid "Unknown plugin \"{plugin_id}\"."
12091209
msgstr ""
12101210

12111211
#, python-brace-format
1212-
msgid "Unknown plugin \"{plugin_id}\"."
1212+
msgid "Untranslated locale {locale}."
12131213
msgstr ""
12141214

12151215
msgid "Update all existing translations"
@@ -1267,8 +1267,8 @@ msgid "Where do you want to save your project's configuration file?"
12671267
msgstr ""
12681268

12691269
msgid ""
1270-
"Which language should your project site be generated in? Enter an IETF "
1271-
"BCP 47 language code."
1270+
"Which language should your project site be generated in? Enter a language"
1271+
" code."
12721272
msgstr ""
12731273

12741274
msgid "Wikipedia contributors"

betty/assets/locale/betty.pot

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ msgid ""
88
msgstr ""
99
"Project-Id-Version: Betty VERSION\n"
1010
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
11-
"POT-Creation-Date: 2025-11-25 02:03+0000\n"
11+
"POT-Creation-Date: 2025-11-27 01:37+0000\n"
1212
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
1313
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1414
"Language-Team: LANGUAGE <[email protected]>\n"
@@ -672,7 +672,7 @@ msgid "Locale aliases must not contain slashes."
672672
msgstr ""
673673

674674
#, python-brace-format
675-
msgid "Locale {locale} is not supported by your system."
675+
msgid "Locale {locale} is not known by your system."
676676
msgstr ""
677677

678678
msgid "Locality"
@@ -1182,11 +1182,11 @@ msgid "Unknown key: {unknown_key}."
11821182
msgstr ""
11831183

11841184
#, python-brace-format
1185-
msgid "Unknown locale {locale}."
1185+
msgid "Unknown plugin \"{plugin_id}\"."
11861186
msgstr ""
11871187

11881188
#, python-brace-format
1189-
msgid "Unknown plugin \"{plugin_id}\"."
1189+
msgid "Untranslated locale {locale}."
11901190
msgstr ""
11911191

11921192
msgid "Update all existing translations"
@@ -1244,8 +1244,8 @@ msgid "Where do you want to save your project's configuration file?"
12441244
msgstr ""
12451245

12461246
msgid ""
1247-
"Which language should your project site be generated in? Enter an IETF BCP"
1248-
" 47 language code."
1247+
"Which language should your project site be generated in? Enter a language "
1248+
"code."
12491249
msgstr ""
12501250

12511251
msgid "Wikipedia contributors"

betty/assets/locale/de-DE/betty.po

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ msgid ""
77
msgstr ""
88
"Project-Id-Version: Betty VERSION\n"
99
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
10-
"POT-Creation-Date: 2025-11-25 02:03+0000\n"
10+
"POT-Creation-Date: 2025-11-27 01:37+0000\n"
1111
"PO-Revision-Date: 2025-03-28 20:02+0000\n"
1212
"Last-Translator: Ettore Atalan <[email protected]>\n"
1313
"Language: de_DE\n"
@@ -708,7 +708,7 @@ msgid "Locale aliases must not contain slashes."
708708
msgstr "Gebietsschema-Aliase dürfen keine Schrägstriche enthalten."
709709

710710
#, python-brace-format
711-
msgid "Locale {locale} is not supported by your system."
711+
msgid "Locale {locale} is not known by your system."
712712
msgstr ""
713713

714714
msgid "Locality"
@@ -1236,11 +1236,11 @@ msgid "Unknown key: {unknown_key}."
12361236
msgstr "Unbekannter Schlüssel: {unknown_key}."
12371237

12381238
#, python-brace-format
1239-
msgid "Unknown locale {locale}."
1239+
msgid "Unknown plugin \"{plugin_id}\"."
12401240
msgstr ""
12411241

12421242
#, python-brace-format
1243-
msgid "Unknown plugin \"{plugin_id}\"."
1243+
msgid "Untranslated locale {locale}."
12441244
msgstr ""
12451245

12461246
msgid "Update all existing translations"
@@ -1300,8 +1300,8 @@ msgid "Where do you want to save your project's configuration file?"
13001300
msgstr ""
13011301

13021302
msgid ""
1303-
"Which language should your project site be generated in? Enter an IETF "
1304-
"BCP 47 language code."
1303+
"Which language should your project site be generated in? Enter a language"
1304+
" code."
13051305
msgstr ""
13061306

13071307
msgid "Wikipedia contributors"

betty/assets/locale/fr-FR/betty.po

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ msgid ""
77
msgstr ""
88
"Project-Id-Version: PROJECT VERSION\n"
99
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
10-
"POT-Creation-Date: 2025-11-25 02:03+0000\n"
10+
"POT-Creation-Date: 2025-11-27 01:37+0000\n"
1111
"PO-Revision-Date: 2025-08-27 20:02+0000\n"
1212
"Last-Translator: \"David D.\" <[email protected]>\n"
1313
"Language: fr_FR\n"
@@ -691,7 +691,7 @@ msgid "Locale aliases must not contain slashes."
691691
msgstr ""
692692

693693
#, python-brace-format
694-
msgid "Locale {locale} is not supported by your system."
694+
msgid "Locale {locale} is not known by your system."
695695
msgstr ""
696696

697697
msgid "Locality"
@@ -1203,11 +1203,11 @@ msgid "Unknown key: {unknown_key}."
12031203
msgstr ""
12041204

12051205
#, python-brace-format
1206-
msgid "Unknown locale {locale}."
1206+
msgid "Unknown plugin \"{plugin_id}\"."
12071207
msgstr ""
12081208

12091209
#, python-brace-format
1210-
msgid "Unknown plugin \"{plugin_id}\"."
1210+
msgid "Untranslated locale {locale}."
12111211
msgstr ""
12121212

12131213
msgid "Update all existing translations"
@@ -1267,11 +1267,9 @@ msgid "Where do you want to save your project's configuration file?"
12671267
msgstr "Où voulez-vous enregistrer le fichier de configuration de votre projet ?"
12681268

12691269
msgid ""
1270-
"Which language should your project site be generated in? Enter an IETF "
1271-
"BCP 47 language code."
1270+
"Which language should your project site be generated in? Enter a language"
1271+
" code."
12721272
msgstr ""
1273-
"Dans quelle langue doit être généré le site de votre projet ? Entrez un "
1274-
"code de langue IETF BCP 47."
12751273

12761274
msgid "Wikipedia contributors"
12771275
msgstr "Contributeurs Wikipédia"

0 commit comments

Comments
 (0)