Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[bug] Can't use gettext_lazy in django settings.py (provide an alternative) #648

Open
rochacbruno opened this issue Aug 26, 2021 · 3 comments
Labels
bug hacktoberfest LazyIssue Related to lazy evaluation such as @format etc...
Milestone

Comments

@rochacbruno
Copy link
Member

from django.utils.translation import gettext_lazy as _

# Default language
LANGUAGE_CODE = 'en-us'

LANGUAGES = [
    ('ja', _('Japanese')),
    ('nl', _('Dutch')),
    ('fr', _('French')),
    ('es', _('Spanish')),
    ('zh-hans', _('Chinese')),
    ('en-us', _('English (USA)')),
]
Traceback (most recent call last):
  File "/venv/lib64/python3.8/site-packages/django/utils/translation/trans_real.py", line 194, in _add_installed_apps_translations
    app_configs = reversed(list(apps.get_app_configs()))
  File "/venv/lib64/python3.8/site-packages/django/apps/registry.py", line 145, in get_app_configs
    self.check_apps_ready()
  File "/venv/lib64/python3.8/site-packages/django/apps/registry.py", line 136, in check_apps_ready
    raise AppRegistryNotReady("Apps aren't loaded yet.")
django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/venv/bin/django-admin", line 8, in <module>
    sys.exit(execute_from_command_line())
  File "/venv/lib64/python3.8/site-packages/django/core/management/__init__.py", line 419, in execute_from_command_line
    utility.execute()
  File "/venv/lib64/python3.8/site-packages/django/core/management/__init__.py", line 363, in execute
    settings.INSTALLED_APPS
  File "/venv/lib64/python3.8/site-packages/django/conf/__init__.py", line 82, in __getattr__
    self._setup(name)
  File "/venv/lib64/python3.8/site-packages/django/conf/__init__.py", line 69, in _setup
    self._wrapped = Settings(settings_module)
  File "/venv/lib64/python3.8/site-packages/django/conf/__init__.py", line 170, in __init__
    mod = importlib.import_module(self.SETTINGS_MODULE)
  File "/usr/lib64/python3.8/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 783, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/src/pulpcore/pulpcore/app/settings.py", line 292, in <module>
    settings = dynaconf.DjangoDynaconf(
  File "/venv/lib64/python3.8/site-packages/dynaconf/contrib/django_dynaconf_v2.py", line 79, in load
    lazy_settings.populate_obj(django_settings_module)
  File "/venv/lib64/python3.8/site-packages/dynaconf/base.py", line 154, in __getattr__
    self._setup()
  File "/venv/lib64/python3.8/site-packages/dynaconf/base.py", line 204, in _setup
    self._wrapped = Settings(
  File "/venv/lib64/python3.8/site-packages/dynaconf/base.py", line 269, in __init__
    self.execute_loaders()
  File "/venv/lib64/python3.8/site-packages/dynaconf/base.py", line 997, in execute_loaders
    self.pre_load(env, silent=silent, key=key)
  File "/venv/lib64/python3.8/site-packages/dynaconf/base.py", line 1015, in pre_load
    self.load_file(path=preloads, env=env, silent=silent, key=key)
  File "/venv/lib64/python3.8/site-packages/dynaconf/base.py", line 1042, in load_file
    if py_loader.try_to_load_from_py_module_name(
  File "/venv/lib64/python3.8/site-packages/dynaconf/loaders/py_loader.py", line 61, in try_to_load_from_py_module_name
    mod = importlib.import_module(str(name))
  File "/usr/lib64/python3.8/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 783, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/src/pulp_ansible/pulp_ansible/app/settings.py", line 24, in <module>
    ANSIBLE_CONTENT_HOSTNAME = settings.CONTENT_ORIGIN + "/pulp/content"
  File "/venv/lib64/python3.8/site-packages/dynaconf/base.py", line 154, in __getattr__
    self._setup()
  File "/venv/lib64/python3.8/site-packages/dynaconf/base.py", line 204, in _setup
    self._wrapped = Settings(
  File "/venv/lib64/python3.8/site-packages/dynaconf/base.py", line 269, in __init__
    self.execute_loaders()
  File "/venv/lib64/python3.8/site-packages/dynaconf/base.py", line 997, in execute_loaders
    self.pre_load(env, silent=silent, key=key)
  File "/venv/lib64/python3.8/site-packages/dynaconf/base.py", line 1015, in pre_load
    self.load_file(path=preloads, env=env, silent=silent, key=key)
  File "/venv/lib64/python3.8/site-packages/dynaconf/base.py", line 1042, in load_file
    if py_loader.try_to_load_from_py_module_name(
  File "/venv/lib64/python3.8/site-packages/dynaconf/loaders/py_loader.py", line 62, in try_to_load_from_py_module_name
    load_from_python_object(obj, mod, name, key, identifier)
  File "/venv/lib64/python3.8/site-packages/dynaconf/loaders/py_loader.py", line 35, in load_from_python_object
    obj.set(
  File "/venv/lib64/python3.8/site-packages/dynaconf/base.py", line 848, in set
    value = parse_conf_data(value, tomlfy=tomlfy, box_settings=self)
  File "/venv/lib64/python3.8/site-packages/dynaconf/utils/parse_conf.py", line 302, in parse_conf_data
    return [
  File "/venv/lib64/python3.8/site-packages/dynaconf/utils/parse_conf.py", line 303, in <listcomp>
    parse_conf_data(item, tomlfy=tomlfy, box_settings=box_settings)
  File "/venv/lib64/python3.8/site-packages/dynaconf/utils/parse_conf.py", line 302, in parse_conf_data
    return [
  File "/venv/lib64/python3.8/site-packages/dynaconf/utils/parse_conf.py", line 303, in <listcomp>
    parse_conf_data(item, tomlfy=tomlfy, box_settings=box_settings)
  File "/venv/lib64/python3.8/site-packages/dynaconf/utils/parse_conf.py", line 317, in parse_conf_data
    return _parse_conf_data(data, tomlfy=tomlfy, box_settings=box_settings)
  File "/venv/lib64/python3.8/site-packages/dynaconf/utils/parse_conf.py", line 271, in _parse_conf_data
    if (
  File "/venv/lib64/python3.8/site-packages/django/utils/functional.py", line 135, in __wrapper__
    res = func(*self.__args, **self.__kw)
  File "/venv/lib64/python3.8/site-packages/django/utils/translation/__init__.py", line 94, in gettext
    return _trans.gettext(message)
  File "/venv/lib64/python3.8/site-packages/django/utils/translation/trans_real.py", line 355, in gettext
    _default = _default or translation(settings.LANGUAGE_CODE)
  File "/venv/lib64/python3.8/site-packages/django/utils/translation/trans_real.py", line 268, in translation
    _translations[language] = DjangoTranslation(language)
  File "/venv/lib64/python3.8/site-packages/django/utils/translation/trans_real.py", line 155, in __init__
    self._add_installed_apps_translations()
  File "/venv/lib64/python3.8/site-packages/django/utils/translation/trans_real.py", line 196, in _add_installed_apps_translations
    raise AppRegistryNotReady(
django.core.exceptions.AppRegistryNotReady: The translation infrastructure cannot be initialized before the apps registry is ready. Check that you don't make non-lazy gettext calls at import time.
@justinmayer
Copy link

This error also seems to occur with non-lazy gettext calls. For example, I get the same error shown in this issue's description via the following import:

from django.utils.translation import gettext as _

Any chance of a fix landing in the near future? 😅

@rochacbruno
Copy link
Member Author

Hi @justinmayer

The problem is that we can't use the translation inside the settings file because dynaconf settings are loaded before the Django App is available.

My plan is to provide an alternative way of doing it but I had no time yet to give a try.

My idea is:

django_app/settings.py

import dynaconf

_ = dynaconf.utils.translation.gettext_lazy

# then you can do

THING = _("Some text here")
...


settings = dynaconf.DjangoDynaconf(....)

The _ object will be a Lazy dynaconf object already defined in dynaconf.utils.parse_conf, that class accepts a formatter argument and that will be the original django.utils.translation.gettext_lazy.

dynaconf/utils/translation.py

from .parse_conf import Lazy

def make_translation(value, **context):
    from django.utils.translation import gettext_lazy
    return gettext_lazy(value)

gettext_lazy = lambda value: Lazy(value, formatter=make_translation)

I had no chance yet to test this solution, but I am guessing it will work because the Lazy object is formatted only when it is accessed by the first time.

@rochacbruno rochacbruno added this to the 3.2.0 milestone Mar 31, 2022
@rochacbruno rochacbruno modified the milestones: 3.2.0, 4.0.0 Sep 21, 2022
@rochacbruno rochacbruno added the LazyIssue Related to lazy evaluation such as @format etc... label Sep 22, 2022
@rochacbruno rochacbruno modified the milestones: 4.0.0, 3.2.0 Sep 22, 2022
@washiur17
Copy link

Using "from django.utils.translation import gettext_lazy as _"
instead of "from django.utils.translation import gettext as _" in apps.py files inside my app folders solved my problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug hacktoberfest LazyIssue Related to lazy evaluation such as @format etc...
Projects
None yet
Development

No branches or pull requests

3 participants