Commit 99fb99718 for llama.cpp
commit 99fb997184c5598b965a704575ca06ed4ed3ae05
Author: Tarek Dakhran <tarek@liquid.ai>
Date: Wed Oct 21 23:06:56 2026 +0200
jinja : fix namespace attributes shadowed by dict methods (#30941)
diff --git a/common/jinja/value.cpp b/common/jinja/value.cpp
index 5ecff52a1..0840e05b8 100644
--- a/common/jinja/value.cpp
+++ b/common/jinja/value.cpp
@@ -425,7 +425,12 @@ const func_builtins & global_builtins() {
throw raised_exception("Jinja Exception: " + msg);
}},
{"dict", toobject},
- {"namespace", toobject},
+ {"namespace", [](const func_args & args) -> value {
+ // unlike a dict, a namespace has no methods: ns.items is the attribute, as in jinja2
+ value out = toobject(args);
+ cast_val<value_object>(out)->has_builtins = false;
+ return out;
+ }},
{"strftime_now", [](const func_args & args) -> value {
args.ensure_vals<value_string>();
std::string format = args.get_pos(0)->as_string().str();
diff --git a/tests/test-jinja.cpp b/tests/test-jinja.cpp
index 327ab365c..99552a8f7 100644
--- a/tests/test-jinja.cpp
+++ b/tests/test-jinja.cpp
@@ -1299,6 +1299,18 @@ static void test_namespace(testing & t) {
json::object(),
"3"
);
+
+ test_template(t, "namespace attribute named like a dict method",
+ "{% set ns = namespace(items=[]) %}{{ 'yes' if ns.items else 'no' }}{% set ns.items = ns.items + [1] %}{{ ns.items | length }}{{ 'yes' if ns.items else 'no' }}",
+ json::object(),
+ "no1yes"
+ );
+
+ test_template(t, "dict keeps its methods",
+ "{% set d = dict(items=1) %}{% for k, v in d.items() %}{{ k }}={{ v }}{% endfor %}",
+ json::object(),
+ "items=1"
+ );
}
static void test_tests(testing & t) {