# Python Fluent chooses wrong locales

**URL:** <https://discourse.mozilla.org/t/python-fluent-chooses-wrong-locales/75049>\
**Category:** Fluent\
**Tags:** issue\
**Created:** [February 5, 2021, 5:26pm UTC](https://discourse.mozilla.org/t/python-fluent-chooses-wrong-locales/75049 "2021-02-05T17:26:05Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![henr](https://avatars.discourse-cdn.com/v4/letter/h/8c91f0/32.png) [@henr](https://discourse.mozilla.org/u/henr)\
**Post date:** [February 5, 2021, 5:26pm UTC](https://discourse.mozilla.org/t/python-fluent-chooses-wrong-locales/75049/1 "2021-02-05T17:26:05Z")

</div>

Hi!

I have implemented Fluent in my Python/Kivy app. I thought it worked fine, but now it seems to ignore when I change locales. Here is the (global) initialization in my Python app:

from fluent.runtime import FluentLocalization, FluentResourceLoader  
loader = FluentResourceLoader(“languages/{locale}”)  
language = FluentLocalization([“en”, “es”, “da”], [“main.ftl”], loader)

Later the user can change the selection, for instance like this:

language.locales = [‘da’,‘en’,‘es’]

AFTER that change, I instantiate a class that uses this in init:

```
    self.label_text = language.format_value("train-ideogram-label")

```

So why does that result in the string from “en” and not the one from “da”?

---

<div class="post-metadata">

**Author:** ![axel](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/axel/32/40432_2.png) [@axel](https://discourse.mozilla.org/u/axel)\
**Post date:** [February 5, 2021, 7:51pm UTC](https://discourse.mozilla.org/t/python-fluent-chooses-wrong-locales/75049/2 "2021-02-05T19:51:21Z")

</div>

Simply put, this works as designed.

The localization class caches the bundles it has loaded, which depends on the list of languages.

All properties are read-only after the initial construction. If you want to change them, just create a new instance.

Would it help to make that more crisp in the documentation?

---

<div class="post-metadata">

**Author:** ![henr](https://avatars.discourse-cdn.com/v4/letter/h/8c91f0/32.png) [@henr](https://discourse.mozilla.org/u/henr)\
**Post date:** [February 5, 2021, 9:00pm UTC](https://discourse.mozilla.org/t/python-fluent-chooses-wrong-locales/75049/3 "2021-02-05T21:00:11Z")

</div>

OK. Thanks.  
I didn’t notice anything in the doc - [https://www.projectfluent.org/python-fluent/fluent.runtime/stable/usage.html](https://www.projectfluent.org/python-fluent/fluent.runtime/stable/usage.html) - about all properties being read-only. I just assumed I could change the locales list property.

---

<div class="post-metadata">

**Author:** ![henr](https://avatars.discourse-cdn.com/v4/letter/h/8c91f0/32.png) [@henr](https://discourse.mozilla.org/u/henr)\
**Post date:** [February 5, 2021, 9:33pm UTC](https://discourse.mozilla.org/t/python-fluent-chooses-wrong-locales/75049/4 "2021-02-05T21:33:10Z")

</div>

Your reply leads to a new question, which is not particularly about Fluent but a more general Python question:

I instantiated ‘language’ outside of any other class or function, so that it would be accessible globally:

language = FluentLocalization([“en”, “es”, “da”], [“main.ftl”], loader)

How can I make it equally globally accessible if I have to instantiate it inside a method where the user selects a language from a list?

---

<div class="post-metadata">

**Author:** ![spookylukey](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/spookylukey/32/24686_2.png) [@spookylukey](https://discourse.mozilla.org/u/spookylukey)\
**Post date:** [February 6, 2021, 5:13am UTC](https://discourse.mozilla.org/t/python-fluent-chooses-wrong-locales/75049/5 "2021-02-06T05:13:41Z")

</div>

This depends on the kind of app you are writing. Given that you are using Kivy, a single global for this might be fine, in which case you can use the `global` keyword:

```python
from fluent.runtime import FluentLocalization, FluentResourceLoader
localization = None

def change_language(languages):
    global localization
    loader = FluentResourceLoader(“languages/{locale}”)
    localization = FluentLocalization(languages, [“main.ftl”], loader)

# Ensure `localization` is always initialized
change_language([“en”, “es”, “da”])

# Also call `change_language` from other places

```

In other app architectures this could be a bad way to do it, and even with Kivy you may need to worry about other threads or modules that are importing this module and could end up with stale values. It might be better to ask on Kivy forums about what the best pattern for global mutable data is.

---

<div class="post-metadata">

**Author:** ![henr](https://avatars.discourse-cdn.com/v4/letter/h/8c91f0/32.png) [@henr](https://discourse.mozilla.org/u/henr)\
**Post date:** [February 6, 2021, 12:26pm UTC](https://discourse.mozilla.org/t/python-fluent-chooses-wrong-locales/75049/6 "2021-02-06T12:26:31Z")

</div>

Can ‘change\_language()’ be called several times? And thus ‘re-instantiate’ ‘localization = FluentLocalization()’?

---

<div class="post-metadata">

**Author:** ![axel](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/axel/32/40432_2.png) [@axel](https://discourse.mozilla.org/u/axel)\
**Post date:** [February 6, 2021, 2:22pm UTC](https://discourse.mozilla.org/t/python-fluent-chooses-wrong-locales/75049/7 "2021-02-06T14:22:59Z")

</div>

If you’re looking for a global entry point, I’d cache a global function, on languages and resources.

A global variable for the localization class isn’t a good fit with how that class is designed and implemented.

---

<div class="post-metadata">

**Author:** ![henr](https://avatars.discourse-cdn.com/v4/letter/h/8c91f0/32.png) [@henr](https://discourse.mozilla.org/u/henr)\
**Post date:** [February 6, 2021, 3:45pm UTC](https://discourse.mozilla.org/t/python-fluent-chooses-wrong-locales/75049/8 "2021-02-06T15:45:06Z")

</div>

Thank you for the answer!  
But can you explain or exemplify what that means? Or link to an explanation?

---

<div class="post-metadata">

**Author:** ![axel](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/axel/32/40432_2.png) [@axel](https://discourse.mozilla.org/u/axel)\
**Post date:** [February 7, 2021, 11:47am UTC](https://discourse.mozilla.org/t/python-fluent-chooses-wrong-locales/75049/9 "2021-02-07T11:47:58Z")

</div>

Sure, something like:

```python
from functools import lru_cache
from typing import Sequence
from fluent.runtime import FluentLocalization, FluentResourceLoader

@lru_cache
def get_localization(languages: Sequence[str], resources: Sequence[str]) -> FluentLocalization:
    loader = FluentResourceLoader("languages/{locale}")
    return FluentLocalization(languages, resources, loader)

```

---

<div class="post-metadata">

**Author:** ![henr](https://avatars.discourse-cdn.com/v4/letter/h/8c91f0/32.png) [@henr](https://discourse.mozilla.org/u/henr)\
**Post date:** [February 7, 2021, 12:17pm UTC](https://discourse.mozilla.org/t/python-fluent-chooses-wrong-locales/75049/10 "2021-02-07T12:17:02Z")

</div>

Shouldn’t that function be called SET\_localization() instead of GET\_localization() ?  
SET would be the functionality I am looking for, as in:

language = SET\_localization(languages\_list, resources)

```
label_text = language.format_value("press-for-next")
```

---

<div class="post-metadata">

**Author:** ![axel](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/axel/32/40432_2.png) [@axel](https://discourse.mozilla.org/u/axel)\
**Post date:** [February 7, 2021, 4:03pm UTC](https://discourse.mozilla.org/t/python-fluent-chooses-wrong-locales/75049/11 "2021-02-07T16:03:20Z")

</div>

The code snippet I showed is getting a translation class to be used in a local context, with caching of these instances, on top of the caching that happens inside the translation class.

If you’re looking for a way still to make your global work, you’ll need to replace the localization class with one that does what you need. It’s not like you’re loosing a lot, because most of the actual logic in the implementation needs to be done differently for the architecture you’d be looking at.

The built-in localization class is really an opinionated way of implementing the concept, and alternative ways should substitute the one we’re shipping.

---

<div class="post-metadata">

**Author:** ![henr](https://avatars.discourse-cdn.com/v4/letter/h/8c91f0/32.png) [@henr](https://discourse.mozilla.org/u/henr)\
**Post date:** [February 7, 2021, 9:41pm UTC](https://discourse.mozilla.org/t/python-fluent-chooses-wrong-locales/75049/12 "2021-02-07T21:41:02Z")

</div>

Thanks for the suggestions.  
I think I will stick to something more simple for now, like this:

from fluent.runtime import FluentLocalization, FluentResourceLoader  
language = None

‘#’ Only call this ONCE:  
def set\_language(languages):  
global language  
loader = FluentResourceLoader(‘languages/{locale}’)  
language = FluentLocalization(languages, [‘main.ftl’], loader)

PS: It seems I can’t write Python comment lines…
