Opened 2 hours ago
#37071 new Bug
BaseConnectionHandler uses @cached_property and private attribute for settings
| Reported by: | Michael Foley | Owned by: | |
|---|---|---|---|
| Component: | Utilities | Version: | 6.0 |
| Severity: | Normal | Keywords: | |
| Cc: | Michael Foley | Triage Stage: | Unreviewed |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
While working on setting up a Class based backend setup for a project I was having some issues with resetting the backends I was using during testing. When using override_settings the the django settings themselves would override but the backend wouldn't change based on those settings.
After a bit more digging I found the settings property on the BaseConnectionHandler
https://github.com/django/django/blob/017d7f6f12e597e6179de7ffdf330a52c2b22053/django/utils/connection.py#L44
Seeing it was a cached property I followed the reset process outlined in the utillty docs
https://docs.djangoproject.com/en/6.0/ref/utils/
To clear the cached result using
handler.__dict__.pop("settings", None)
But this still didn't seem to clear the settings as expected.
Looking a bit further I found that the BaseConnectionHandler also has a private property of _settings that is also setup as a cache for the settings
def __init__(self, settings=None):
self._settings = settings
self._connections = Local(self.thread_critical)
@cached_property
def settings(self):
self._settings = self.configure_settings(self._settings)
return self._settings
def configure_settings(self, settings):
if settings is None:
settings = getattr(django_settings, self.settings_name)
return settings
So it looks like both @cached_property and a private property are being maintained as caches for the settings.
Updating my reset process to clear the cached property and the _settings property on the backend fixed the testing and the backends would switch without a problem.
I wasn't sure if this was an intentional setup or to support backwards compatibility but it did create a bit of hair pulling as while I was working on it. git blame shows its been there since the connection broker was initially setup.