common : honor case_sensitive argument in jinja sort and dictsort - #24971
common : honor case_sensitive argument in jinja sort and dictsort#24971dnislno wants to merge 1 commit into
Conversation
Assisted-by: opencode (glm-5.2)
|
This is not the right fix, don't bypass |
Thanks for the review. You're right on both points. I'll revise to add a case_sensitive parameter to value_compare instead of bypassing it. For the unicode issue, I see unicode_tolower exists in src/unicode.* but common/ doesn't depend on src/ - do you want me to move it to common/, or keep ASCII-only with a TODO for now? |
Well, this is the main reason it has not been implemented yet (that and that there are no templates relying on this), just lowercasing is probably not enough and I'm not sure we want to move unicode handling. @ngxson any opinions on this? |
|
If this is not related to a reported issue, I don't think it's worth spending time. Sounds like a too nit-fix to me |
|
Understood. Closing the PR. |
Overview
Fix the
case_sensitivekeyword argument being silently ignored in both thesortanddictsortJinja filters incommon/jinja/value.cpp.Both filters read
case_sensitivefrom kwargs but the line that applies it was commented out with aFIXME: sorting is currently always case sensitivemarker. As a result,{{ items | sort(case_sensitive=false) }}and{{ obj | dictsort(case_sensitive=false) }}silently perform a case-sensitive sort - the argument is accepted without error but has no effect.Related issues/PRs
This fix completes the scaffolding left unfinished in these merged PRs:
jinja : attribute support for join, map and sort(CISC, merged Jan 18, 2026): introduced thecase_sensitivekwarg to thesortfilter and left it commented out with FIXME. In review, CISC said "case_sensitive=Falseis default, but we are always case sensitive ATM" and promised a follow-up.jinja : implement mixed type object keys(CISC, merged Jan 27, 2026): CISC's next PR, but addressed mixed type object keys, notcase_sensitive. The promised follow-up never landed.implement new jinja template engine(ngxson, merged Jan 16, 2026): the original PR that introduced the new Jinja engine, where thedictsortFIXME was also present.No standalone issue was ever filed for this bug. The FIXME has been sitting in master for 5 months with no fix attempt.
Source locations
File:
common/jinja/value.cppSite 1 -
sortfilter (value_array_t::get_builtins, line 1080):Before (lines 1080-1081):
After (line 1080 + new branch at line 1099):
And inside the sort comparator, after attribute extraction, before the
value_comparecall:Site 2 -
dictsortfilter (value_object_t::get_builtins, line 1201):Before (lines 1201-1202):
After (line 1201 + unified comparator at line 1206):
And the comparator refactored from
if/elseto unifiedval_a/val_bselection + same case-insensitive branch.Local testing
Tested locally on Windows with pre-built
llama-server(buildb9747-d6d899580) andgemma-4-E2B-it-qat-UD-Q4_K_XL.gguf.Before fix - probe template
{{ ['Banana', 'apple', 'Cherry', 'date'] | sort(case_sensitive=false) | join(',') }}rendered via/apply-templateendpoint:Output is ASCII codepoint order -
case_sensitive=falsewas ignored. Confirmed on the real binary.After fix - logic simulation of the patched comparator (no compiler available locally to rebuild the DLL):
Matches Jinja2 spec for case-insensitive ascending sort.
Regression checks passed:
case_sensitive=trueunchanged in both filtersreverse=trueproduces correct descending case-insensitive orderdictsortby=keyandby=valuepaths both coveredllama-bench(pp512=39.62 t/s, tg128=10.72 t/s) andllama-perplexitybaselines run without crashChanges summary
case_sensitivebinding in both filters (2 lines removed, 2 lines added)sortcomparator (+5 lines)dictsortcomparator to unifiedval_a/val_b+ same branch (net +4 lines).as_string().lowercase()(already used bylowerfilter, line 607) and.str()(already used invalue_compare, line 1336) - no new helperscase_sensitive=trueand non-string comparisons fall through to existingvalue_compareunchangedTests added
File:
tests/test-jinja.cppTest inputs use distinct lowercased values to avoid
std::sortinstability on ties.Requirements
llama-serverbinary to confirm the bug before fix, writing a Python logic simulation to verify the fix after, and runningllama-bench/llama-perplexitybaselines. The fix itself is human-authored and understood: uncomment existing scaffolding + add a lowercased-string compare branch mirroring an existing pattern (lowerfilter at line 607), applied to bothsortanddictsort.