-
-
Notifications
You must be signed in to change notification settings - Fork 318
[bug] CLI not working with Django on master #949
Copy link
Copy link
Closed
Labels
Description
On master branch the CLI is not working in a Django app
Steps to Reproduce
❯ cd tests_functional/django_example
❯ DJANGO_SETTINGS_MODULE=foo.settings PYTHONPATH=. dynaconf list
Django app detected
╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
│ │
│ /home/rochacbruno/Projects/dynaconf/dynaconf/cli.py:546 in _list │
│ │
│ 543 │ if env: │
│ 544 │ │ settings.setenv(env) │
│ 545 │ │
│ ❱ 546 │ cur_env = settings.current_env.lower() │
│ 547 │ │
│ 548 │ if cur_env == "main": │
│ 549 │ │ flat = True │
│ │
│ ╭───────────────────────────────── locals ─────────────────────────────────╮ │
│ │ _all = False │ │
│ │ ctx = <dynaconf.vendor.click.core.Context object at 0x7f4d5a77c130> │ │
│ │ env = None │ │
│ │ flat = False │ │
│ │ key = None │ │
│ │ loader = None │ │
│ │ more = None │ │
│ │ output = None │ │
│ │ settings = <LazySettings "foo.settings"> │ │
│ ╰──────────────────────────────────────────────────────────────────────────╯ │
│ │
│ /home/rochacbruno/Projects/dynaconf/.venv/lib/python3.8/site-packages/django/conf/__init__.py:88 │
│ in __getattr__ │
│ │
│ 85 │ │ """Return the value of a setting and cache it in self.__dict__.""" │
│ 86 │ │ if self._wrapped is empty: │
│ 87 │ │ │ self._setup(name) │
│ ❱ 88 │ │ val = getattr(self._wrapped, name) │
│ 89 │ │ │
│ 90 │ │ # Special case some settings which require further modification. │
│ 91 │ │ # This is done here for performance reasons so the modified value is cached. │
│ │
│ ╭─────────────── locals ───────────────╮ │
│ │ name = 'current_env' │ │
│ │ self = <LazySettings "foo.settings"> │ │
│ ╰──────────────────────────────────────╯ │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
AttributeError: 'Settings' object has no attribute 'current_env'
Same error happens with get command
❯ DJANGO_SETTINGS_MODULE=foo.settings PYTHONPATH=. dynaconf get DEBUG
│ /home/rochacbruno/Projects/dynaconf/dynaconf/cli.py:475 in get │
│ │
│ 472 │ if default is not empty: │
│ 473 │ │ result = settings.get(key, default) │
│ 474 │ else: │
│ ❱ 475 │ │ result = settings[key] # let the keyerror raises │
│ 476 │ │
│ 477 │ if unparse: │
│ 478 │ │ result = unparse_conf_data(result) │
│ │
│ ╭───────────────────────────────── locals ─────────────────────────────────╮ │
│ │ ctx = <dynaconf.vendor.click.core.Context object at 0x7f32e513c130> │ │
│ │ default = <dynaconf.utils.functional.Empty object at 0x7f32e4a5d0d0> │ │
│ │ env = None │ │
│ │ key = 'DEBUG' │ │
│ │ settings = <LazySettings "foo.settings"> │ │
│ │ unparse = False │ │
│ ╰──────────────────────────────────────────────────────────────────────────╯ │
│ │
│ /home/rochacbruno/Projects/dynaconf/.venv/lib/python3.8/site-packages/django/utils/functional.py │
│ :259 in inner │
│ │
│ 256 │ def inner(self, *args): │
│ 257 │ │ if self._wrapped is empty: │
│ 258 │ │ │ self._setup() │
│ ❱ 259 │ │ return func(self._wrapped, *args) │
│ 260 │ │
│ 261 │ return inner │
│ 262 │
│ │
│ ╭─────────────── locals ───────────────╮ │
│ │ args = ('DEBUG',) │ │
│ │ func = <built-in function getitem> │ │
│ │ self = <LazySettings "foo.settings"> │ │
│ ╰──────────────────────────────────────╯ │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
TypeError: 'Settings' object is not subscriptable
And also the new inspect command
│ /home/rochacbruno/Projects/dynaconf/dynaconf/utils/inspect.py:79 in inspect_settings │
│ │
│ 76 │ original_settings = settings │
│ 77 │ settings = settings if not env else settings.from_env(env) │
│ 78 │ │
│ ❱ 79 │ setting_envs = {_env.env for _env in settings._loaded_by_loaders.keys()} │
│ 80 │ if env and env.lower() not in setting_envs: │
│ 81 │ │ raise EnvNotFoundError(f"The requested env is not valid: {env!r}") │
│ 82 │
│ │
│ ╭───────────────────── locals ──────────────────────╮ │
│ │ ascending_order = True │ │
│ │ custom_dumper = None │ │
│ │ env = '' │ │
│ │ key_dotted_path = 'DEBUG' │ │
│ │ original_settings = <LazySettings "foo.settings"> │ │
│ │ output_format = 'json' │ │
│ │ settings = <LazySettings "foo.settings"> │ │
│ │ to_file = '' │ │
│ ╰───────────────────────────────────────────────────╯ │
│ │
│ /home/rochacbruno/Projects/dynaconf/.venv/lib/python3.8/site-packages/django/conf/__init__.py:88 │
│ in __getattr__ │
│ │
│ 85 │ │ """Return the value of a setting and cache it in self.__dict__.""" │
│ 86 │ │ if self._wrapped is empty: │
│ 87 │ │ │ self._setup(name) │
│ ❱ 88 │ │ val = getattr(self._wrapped, name) │
│ 89 │ │ │
│ 90 │ │ # Special case some settings which require further modification. │
│ 91 │ │ # This is done here for performance reasons so the modified value is cached. │
│ │
│ ╭─────────────── locals ───────────────╮ │
│ │ name = '_loaded_by_loaders' │ │
│ │ self = <LazySettings "foo.settings"> │ │
│ ╰──────────────────────────────────────╯ │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
AttributeError: 'Settings' object has no attribute '_loaded_by_loaders'
Investigation
In the django context the settings is being applied correctly
❯ DJANGO_SETTINGS_MODULE=foo.settings PYTHONPATH=. django-admin shell
In [1]: from django.conf import settings
In [2]: settings.__class__
Out[2]: dynaconf.base.Settings
However I added a breakpoint on line 545 of cli.py and figured out that settings there is a bare Django.conf.settings not a dynaconf.base.Settings instance, for some reason the dynaconf plugin is not being loaded at that point.
Expected
At the same directory, checking out to 3.2.12 branch everything works as expected.
❯ git checkout 3.1.12
❯ DJANGO_SETTINGS_MODULE=foo.settings PYTHONPATH=. dynaconf list
Django app detected
Working in production environment
BASE_DIR<str> '/home/rochacbruno/Projects/dynaconf/tests_functional/django_example'
STATIC_URL<str> '/static/'
...
❯ DJANGO_SETTINGS_MODULE=foo.settings PYTHONPATH=. dynaconf get DEBUG
True%
## Inspect command does not exist on that version.
❯ DJANGO_SETTINGS_MODULE=foo.settings PYTHONPATH=. django-admin shell
In [1]: from django.conf import settings
In [2]: settings.__class__
Out[2]: dynaconf.base.Settings
Reactions are currently unavailable