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) {