#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 , 4 years ago
| Component: | Core (Other) → Utilities |
|---|---|
| Resolution: | → needsinfo |
| Status: | new → closed |
| Type: | Uncategorized → Cleanup/optimization |
comment:2 by , 4 years ago
| Summary: | isinstance(LazyConfig, str) raises Excepion → isinstance() checks with non-configured LazySettings raise an exception. |
|---|
comment:3 by , 4 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 , 4 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 , 4 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
LazySettingsis an internal undocumented tool and the error message sounds good.Can you describe your use case?