Opened 12 months ago

Closed 12 months ago

Last modified 12 months ago

#33362 closed Bug (invalid)

ALLOWED_HOSTS no longer accepts a non-list/tuple iterable.

Reported by: Carlton Gibson Owned by: nobody
Component: HTTP handling Version: 4.0
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


cdd0b213a825fcfe90ae93dcc554fba8c1e5ff5d added ALLOWED_HOSTS to the list of tuple_settings that are checked to be lists or tuples in Settings.__init__().

This causes a regression with settings such as:

class AllowedHosts:
    An allowed hosts proxy, implementing SOME logic to determine ALLOWED_HOSTS.

    DEBUG_ALLOWED_HOSTS = ["localhost", "", "[::1]"]

    def __iter__(self):
        if settings.DEBUG:
            yield from self.DEBUG_ALLOWED_HOSTS

        yield ""
        yield ""
        yield from [
ALLOWED_HOSTS = AllowedHosts()

This works fine before Django 4.0 but raises afterwards:

raise ImproperlyConfigured("The %s setting must be a list or a tuple." % setting)
django.core.exceptions.ImproperlyConfigured: The ALLOWED_HOSTS setting must be a list or a tuple.

We could revert cdd0b213a825fcfe90ae93dcc554fba8c1e5ff5d, or else adjust the test. I think the force of it is "iterable() but not a string"? 🤔

Change History (5)

comment:1 Changed 12 months ago by Mariusz Felisiak

Resolution: invalid
Status: newclosed

It's documented that ALLOWED_HOSTS is "a list of strings representing...", it was also discussed in one of PRs. I wouldn't consider it as a regression, sorry :) I'm of course open to discussion.

comment:2 Changed 12 months ago by Carlton Gibson

OK, we can say that 😜
(It’s worked this way since ≈forever, so it is a change in behaviour, but there’ll be another way.)

comment:3 Changed 12 months ago by Adam Johnson

There's nothing complicated about your class there, it can be determined at import time right? It only depends on whether DEBUG is True or not.

You could always make your setting a subclass of list and override __iter__ if really required.

comment:4 Changed 12 months ago by Carlton Gibson

The example is simplified, but I can work around, yes. I do feel we've cut out a legitimate use-case with an overly strict test — it demands more than we need — but it's not something I want to spend time pushing on now. (Not a problem!)

comment:5 Changed 12 months ago by Claude Paroz

I agree with Carlton, those checks are not totally Pythonic (duck typing and all...) and could probably be improved.

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