#32894 closed Cleanup/optimization (needsinfo)
isinstance() checks with non-configured LazySettings raise an exception.
Reported by: | simon klemenc | Owned by: | nobody |
---|---|---|---|
Component: | Utilities | Version: | 3.2 |
Severity: | Normal | Keywords: | lazyobject lazysettings |
Cc: | Keryn Knight | Triage Stage: | Unreviewed |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | yes | UI/UX: | no |
Description
steps to reproduce:
import django.conf settings = django.conf.LazySettings() isinstance(settings, dict) --------------------------------------------------------------------------- ImproperlyConfigured Traceback (most recent call last) <ipython-input-36-201b302c2983> in <module> 2 3 settings = django.conf.LazySettings() ----> 4 isinstance(settings, str) ~/.local/lib/python3.9/site-packages/django/utils/functional.py in inner(self, *args) 244 def inner(self, *args): 245 if self._wrapped is empty: --> 246 self._setup() 247 return func(self._wrapped, *args) 248 return inner ~/.local/lib/python3.9/site-packages/django/conf/__init__.py in _setup(self, name) 61 if not settings_module: 62 desc = ("setting %s" % name) if name else "settings" ---> 63 raise ImproperlyConfigured( 64 "Requested %s, but settings are not configured. " 65 "You must either define the environment variable %s " ImproperlyConfigured: Requested settings, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.
isinstance is accessing class which wants to setup the lazyobject
maybe class should fall back to returning the "LazyObject"
Change History (6)
comment:1 by , 3 years ago
Component: | Core (Other) → Utilities |
---|---|
Resolution: | → needsinfo |
Status: | new → closed |
Type: | Uncategorized → Cleanup/optimization |
comment:2 by , 3 years ago
Summary: | isinstance(LazyConfig, str) raises Excepion → isinstance() checks with non-configured LazySettings raise an exception. |
---|
comment:3 by , 3 years ago
Thanks for the response,
the use case is a quite specific problem i encountered:
here some kind of garbage-cleanup fails because isinstance(LazyConfig, XX) fails...
To fix the tests, in the class method the setup could be catched in a try/except.
My personal feeling is that a type check should work always...?
comment:4 by , 3 years ago
I was baffled by you mentioning pyqtgraph
here which doesn't use Django.
I did some digging which came up with this issue, however.
Are you using PyCharm? (Just wondering if it is the same problem.)
comment:5 by , 3 years ago
Cc: | added |
---|
Adding a note to say that whilst I understand why it's closed, I think I have just been bitten by this in a similarly niche scenario: trying to use pympler's tracking module threw an error when I tried to run it over the test suite:
File "/path/to/django/tests/runtests.py", line 679, in <module> mem.print_diff() File "/path/to/python3.10/site-packages/pympler/tracker.py", line 138, in print_diff summary.print_(self.diff(summary1=summary1, summary2=summary2)) File "/path/to/python3.10/site-packages/pympler/tracker.py", line 116, in diff self.s1 = self.create_summary() File "/path/to/python3.10/site-packages/pympler/tracker.py", line 91, in create_summary res = summary.summarize(muppy.get_objects()) File "/path/to/python3.10/site-packages/pympler/muppy.py", line 42, in get_objects tmp = [o for o in tmp if not ignore_object(o)] File "/path/to/python3.10/site-packages/pympler/muppy.py", line 42, in <listcomp> tmp = [o for o in tmp if not ignore_object(o)] File "/path/to/python3.10/site-packages/pympler/muppy.py", line 17, in ignore_object return isframe(obj) File "/path/to/python3.10/inspect.py", line 377, in isframe return isinstance(object, types.FrameType) File "/path/to/django/utils/functional.py", line 256, in inner self._setup() File "/path/to/django/contrib/staticfiles/storage.py", line 469, in _setup self._wrapped = get_storage_class(settings.STATICFILES_STORAGE)()
I don't have a proposed solution as such, but it looks like it's attempting to access __class__
when it fails, which would appear (back of the napkin) to be happening before any custom __instancecheck__(...)
call could be implemented, based on a quick bit of pdb
usage :/
comment:6 by , 3 years ago
Continuing to document new ways in which I come across this (always niche, naturally) in case there ever comes a tipping point where it's potentially worth investigating options further.
Running:
monkeytype run -m runtests --parallel=1
against the Django test suite generates a lot of log noise like so:
Failed collecting trace Traceback (most recent call last): File "/path/to/python3.10/site-packages/monkeytype/tracing.py", line 259, in __call__ self.handle_call(frame) File "/path/to/python3.10/site-packages/monkeytype/tracing.py", line 213, in handle_call func = self._get_func(frame) File "/path/to/python3.10/site-packages/monkeytype/tracing.py", line 207, in _get_func self.cache[code] = get_func(frame) File "/path/to/python3.10/site-packages/monkeytype/tracing.py", line 156, in get_func if not isinstance(v, type): File "/path/to/django/utils/functional.py", line 294, in __getattribute__ value = super().__getattribute__(name) File "/path/to/django/utils/functional.py", line 266, in inner self._setup() File "/path/to/django/conf/__init__.py", line 72, in _setup raise ImproperlyConfigured( django.core.exceptions.ImproperlyConfigured: Requested settings, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.
They all seem to be log messages which may not actually present as an error/problem in practice, though (that is, the test suite looks to continue running ... but I gave up on it as it was taking forever)
Thanks for this report, however I don't see any practical issue here 🤔 Moreover
LazySettings
is an internal undocumented tool and the error message sounds good.Can you describe your use case?