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

https://github.com/django/django/blob/017d7f6f12e597e6179de7ffdf330a52c2b22053/django/utils/connection.py#L39

    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.

Change History (0)

Note: See TracTickets for help on using tickets.
Back to Top