-import babel
+from typing import TYPE_CHECKING, Any, Callable, Dict, List, Tuple, Union, cast
+
+import babel
import babel.numbers
import babel.plural
-from typing import Any, Callable, Dict, List, TYPE_CHECKING, Tuple, Union, cast
-from typing_extensions import Literal
-
from fluent.syntax import ast as FTL
+from typing_extensions import Literal
from .builtins import BUILTINS
from .prepare import Compiler
@@ -54,7 +54,7 @@ Source code for fluent.runtime.bundle
if TYPE_CHECKING:
from .types import FluentNone, FluentType
-PluralCategory = Literal['zero', 'one', 'two', 'few', 'many', 'other']
+PluralCategory = Literal["zero", "one", "two", "few", "many", "other"]
[docs]class FluentBundle:
@@ -72,10 +72,12 @@
Source code for fluent.runtime.bundle
See the documentation of the Fluent syntax for more information.
"""
- def __init__(self,
- locales: List[str],
- functions: Union[Dict[str, Callable[[Any], 'FluentType']], None] = None,
- use_isolating: bool = True):
+ def __init__(
+ self,
+ locales: List[str],
+ functions: Union[Dict[str, Callable[[Any], "FluentType"]], None] = None,
+ use_isolating: bool = True,
+ ):
self.locales = locales
self._functions = {**BUILTINS, **(functions or {})}
self.use_isolating = use_isolating
@@ -83,14 +85,22 @@ Source code for fluent.runtime.bundle
self._terms: Dict[str, Union[FTL.Message, FTL.Term]] = {}
self._compiled: Dict[str, Message] = {}
# The compiler is not typed, and this cast is only valid for the public API
- self._compiler = cast(Callable[[Union[FTL.Message, FTL.Term]], Message], Compiler())
+ self._compiler = cast(
+ Callable[[Union[FTL.Message, FTL.Term]], Message], Compiler()
+ )
self._babel_locale = self._get_babel_locale()
- self._plural_form = cast(Callable[[Any], Callable[[Union[int, float]], PluralCategory]],
- babel.plural.to_python)(self._babel_locale.plural_form)
- self._ordinal_form = cast(Callable[[Any], Callable[[Union[int, float]], PluralCategory]],
- babel.plural.to_python)(self._babel_locale.ordinal_form)
-
- def add_resource(self, resource: FTL.Resource, allow_overrides: bool = False) -> None:
+ self._plural_form = cast(
+ Callable[[Any], Callable[[Union[int, float]], PluralCategory]],
+ babel.plural.to_python,
+ )(self._babel_locale.plural_form)
+ self._ordinal_form = cast(
+ Callable[[Any], Callable[[Union[int, float]], PluralCategory]],
+ babel.plural.to_python,
+ )(self._babel_locale.ordinal_form)
+
+ def add_resource(
+ self, resource: FTL.Resource, allow_overrides: bool = False
+ ) -> None:
# TODO - warn/error about duplicates
for item in resource.body:
if not isinstance(item, (FTL.Message, FTL.Term)):
@@ -108,7 +118,7 @@ Source code for fluent.runtime.bundle
def _lookup(self, entry_id: str, term: bool = False) -> Message:
if term:
- compiled_id = '-' + entry_id
+ compiled_id = "-" + entry_id
else:
compiled_id = entry_id
try:
@@ -119,10 +129,9 @@ Source code for fluent.runtime.bundle
self._compiled[compiled_id] = self._compiler(entry)
return self._compiled[compiled_id]
- def format_pattern(self,
- pattern: Pattern,
- args: Union[Dict[str, Any], None] = None
- ) -> Tuple[Union[str, 'FluentNone'], List[Exception]]:
+ def format_pattern(
+ self, pattern: Pattern, args: Union[Dict[str, Any], None] = None
+ ) -> Tuple[Union[str, "FluentNone"], List[Exception]]:
if args is not None:
fluent_args = {
argname: native_to_fluent(argvalue)
@@ -132,20 +141,20 @@ Source code for fluent.runtime.bundle
fluent_args = {}
errors: List[Exception] = []
- env = ResolverEnvironment(context=self,
- current=CurrentEnvironment(args=fluent_args),
- errors=errors)
+ env = ResolverEnvironment(
+ context=self, current=CurrentEnvironment(args=fluent_args), errors=errors
+ )
try:
result = pattern(env)
except ValueError as e:
errors.append(e)
- result = '{???}'
+ result = "{???}"
return (result, errors)
def _get_babel_locale(self) -> babel.Locale:
for lc in self.locales:
try:
- return babel.Locale.parse(lc.replace('-', '_'))
+ return babel.Locale.parse(lc.replace("-", "_"))
except babel.UnknownLocaleError:
continue
# TODO - log error
diff --git a/fluent.runtime/dev/_modules/fluent/runtime/fallback.html b/fluent.runtime/dev/_modules/fluent/runtime/fallback.html
index 228b76a4..cee986d9 100644
--- a/fluent.runtime/dev/_modules/fluent/runtime/fallback.html
+++ b/fluent.runtime/dev/_modules/fluent/runtime/fallback.html
@@ -40,7 +40,17 @@ Navigation
Source code for fluent.runtime.fallback
import codecs
import os
-from typing import Any, Callable, Dict, Generator, List, TYPE_CHECKING, Type, Union, cast
+from typing import (
+ TYPE_CHECKING,
+ Any,
+ Callable,
+ Dict,
+ Generator,
+ List,
+ Type,
+ Union,
+ cast,
+)
from fluent.syntax import FluentParser
@@ -48,6 +58,7 @@ Source code for fluent.runtime.fallback
if TYPE_CHECKING:
from fluent.syntax.ast import Resource
+
from .types import FluentType
@@ -63,10 +74,10 @@ Source code for fluent.runtime.fallback
self,
locales: List[str],
resource_ids: List[str],
- resource_loader: 'AbstractResourceLoader',
+ resource_loader: "AbstractResourceLoader",
use_isolating: bool = False,
bundle_class: Type[FluentBundle] = FluentBundle,
- functions: Union[Dict[str, Callable[[Any], 'FluentType']], None] = None,
+ functions: Union[Dict[str, Callable[[Any], "FluentType"]], None] = None,
):
self.locales = locales
self.resource_ids = resource_ids
@@ -77,7 +88,9 @@ Source code for fluent.runtime.fallback
self._bundle_cache: List[FluentBundle] = []
self._bundle_it = self._iterate_bundles()
- def format_value(self, msg_id: str, args: Union[Dict[str, Any], None] = None) -> str:
+ def format_value(
+ self, msg_id: str, args: Union[Dict[str, Any], None] = None
+ ) -> str:
for bundle in self._bundles():
if not bundle.has_message(msg_id):
continue
@@ -85,7 +98,9 @@ Source code for fluent.runtime.fallback
if not msg.value:
continue
val, _errors = bundle.format_pattern(msg.value, args)
- return cast(str, val) # Never FluentNone when format_pattern called externally
+ return cast(
+ str, val
+ ) # Never FluentNone when format_pattern called externally
return msg_id
def _create_bundle(self, locales: List[str]) -> FluentBundle:
@@ -119,7 +134,9 @@ Source code for fluent.runtime.fallback
Interface to implement for resource loaders.
"""
-[docs] def resources(self, locale: str, resource_ids: List[str]) -> Generator[List['Resource'], None, None]:
+
[docs] def resources(
+
self, locale: str, resource_ids: List[str]
+
) -> Generator[List["Resource"], None, None]:
"""
Yield lists of FluentResource objects, corresponding to
each of the resource_ids.
@@ -148,14 +165,16 @@
Source code for fluent.runtime.fallback
"""
self.roots = [roots] if isinstance(roots, str) else roots
-[docs] def resources(self, locale: str, resource_ids: List[str]) -> Generator[List['Resource'], None, None]:
+
[docs] def resources(
+
self, locale: str, resource_ids: List[str]
+
) -> Generator[List["Resource"], None, None]:
for root in self.roots:
resources: List[Any] = []
for resource_id in resource_ids:
path = self.localize_path(os.path.join(root, resource_id), locale)
if not os.path.isfile(path):
continue
-
content = codecs.open(path, 'r', 'utf-8').read()
+
content = codecs.open(path, "r", "utf-8").read()
resources.append(FluentParser().parse(content))
if resources:
yield resources