Opened 2 hours ago

Last modified 82 minutes ago

#37318 assigned Bug

first, last, and random template filters raise KeyError on a dict instead of failing gracefully — at Initial Version

Reported by: Akshat Kansal Owned by: Akshat Kansal
Component: Template system Version: dev
Severity: Normal Keywords: defaultfilters first last random
Cc: Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

The first, last and random template filters raise KeyError when given a
dictionary, instead of failing gracefully the way they do for an empty list.

How to reproduce

import django
from django.conf import settings
settings.configure(TEMPLATES=[{
    "BACKEND": "django.template.backends.django.DjangoTemplates",
    "DIRS": [], "APP_DIRS": False, "OPTIONS": {},
}])
django.setup()

from django.template import Template, Context

Template("{{ d|first }}").render(Context({"d": []}))        # returns ''
Template("{{ d|first }}").render(Context({"d": {"a": 1}}))  # KeyError: 0
Template("{{ d|last }}").render(Context({"d": {}}))         # KeyError: -1

A list degrades to an empty string. A dict raises KeyError, which escapes
template rendering and becomes a 500. Dicts are common in template contexts,
so this is reachable from an ordinary template.

Why this looks like a bug

first() already catches IndexError so that a wrong-shaped value degrades
instead of raising:

def first(value):
    try:
        return value[0]
    except IndexError:
        return ""

A dict is the same class of mistake as an empty list, but one returns "" and
the other 500s. The inconsistency is the complaint, not the fact that dicts
are unsupported.

I am happy to write the patch and tests if this is accepted.

Reproduced on main @ 5180f82 (6.2.dev).

Run the reproduction yourself before you submit — that part isn't about policy, it's that you'll be asked follow-up questions and should have seen the failure with your own eyes.

Change History (0)

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