﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
29244	Passing dict to a Func subclass fails silently on hash step	Rob Jauquet	nobody	"With this code:

{{{#!python
from django.contrib.postgres.search import SearchQuery, Value, Func
from django.core.paginator import Paginator
from django.db.models import F, TextField, DateTimeField, Models
from django.utils import timezone

class Entry(Model):
    text = TextField()
    published_on = DateTimeField(default=timezone.now())

class Headline(Func):
    function = 'ts_headline'
    output_field = TextField()

    def __init__(self, text, query, options=None):
        extra = {}
        expressions = [text, query]
        if options:
            opt_str = ''
            for key, value in options.items():
                opt_str += f'{key}={value},'
            expressions.append(Value(opt_str[:-1]))
        super().__init__(*expressions, **extra)

entries = Entry.objects.annotate(
    text_highlighted=Headline(
        F('text'), 
        SearchQuery('house'), 
        options={'HighlightAll': False},
    )
).order_by('-published_on')

paginator = Paginator(entries, 20)

# evaluates the queryset
paginator.page(1)
}}}

Passing options by {{{dict}}} to the {{{Func}}} subclass causes the count step for pagination to fail silently in paginator.py line 85 [#link1 (1)] which is in turn caused by a silenced TypeError during the hash in expressions.py line 372 [#link2 (2)]. 

Then, because of the fallback to {{{len}}} on paginator.py line 90 [#link3 (3)] the entire queryset is evaluated instead of evaluating just the specified page (and in this specific case, calling ts_headline on every row instead of just the first page).

The correct way of passing options using {{{**options}}} instead of {{{options=None}}} fixes this case, but the silent error and fallback to calling {{{len}}} on a queryset causes an unexpected expensive query when using pagination.

[=#link1 (1)] https://github.com/django/django/blob/master/django/core/paginator.py#L85
[=#link2 (2)] https://github.com/django/django/blob/master/django/db/models/expressions.py#L372
[=#link3 (3)] https://github.com/django/django/blob/master/django/core/paginator.py#L90"	Bug	new	Core (Other)	2.0	Normal				Unreviewed	0	0	0	0	0	0
