mirror of
https://github.com/ggml-org/llama.cpp.git
synced 2026-09-27 21:46:57 +02:00
jinja : add support for dict builtin (#29477)
* add support for dict builtin * add tests
This commit is contained in:
+39
-12
@@ -348,6 +348,43 @@ static value default_value(const func_args & args) {
|
||||
return no_value ? args.get_pos(1) : args.get_pos(0);
|
||||
}
|
||||
|
||||
static value toobject(const func_args & args) {
|
||||
auto out = mk_val<value_object>();
|
||||
value iter = args.get_pos(0, mk_val<value_undefined>());
|
||||
bool iter_first = false;
|
||||
if (is_val<value_array>(iter)) {
|
||||
iter_first = true;
|
||||
for (const auto & it : iter->as_array()) {
|
||||
if (is_val<value_array>(it) && it->as_array().size() == 2) {
|
||||
auto tuple = it->as_array();
|
||||
auto key = tuple[0];
|
||||
auto val = tuple[1];
|
||||
JJ_DEBUG("namespace/dict: adding key '%s'", key->as_string().str().c_str());
|
||||
out->insert(key, val);
|
||||
} else {
|
||||
throw raised_exception("namespace/dict() iterable argument must consist of tuples, not " + it->type());
|
||||
}
|
||||
}
|
||||
} else if (is_val<value_object>(iter)) {
|
||||
iter_first = true;
|
||||
for (const auto & pair : iter->as_ordered_object()) {
|
||||
JJ_DEBUG("namespace/dict: adding key '%s'", pair.first->as_string().str().c_str());
|
||||
out->insert(pair.first, pair.second);
|
||||
}
|
||||
}
|
||||
for (const auto & arg : args.get_args()) {
|
||||
if (is_val<value_kwarg>(arg)) {
|
||||
auto kwarg = cast_val<value_kwarg>(arg);
|
||||
JJ_DEBUG("namespace/dict: adding key '%s'", kwarg->key.c_str());
|
||||
out->insert(kwarg->key, kwarg->val);
|
||||
} else if (!iter_first) {
|
||||
throw raised_exception("namespace/dict() arguments must be kwargs, dict and/or iterable of tuples, not " + arg->type());
|
||||
}
|
||||
iter_first = false;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
const func_builtins & global_builtins() {
|
||||
static const func_builtins builtins = {
|
||||
{"raise_exception", [](const func_args & args) -> value {
|
||||
@@ -355,18 +392,8 @@ const func_builtins & global_builtins() {
|
||||
std::string msg = args.get_pos(0)->as_string().str();
|
||||
throw raised_exception("Jinja Exception: " + msg);
|
||||
}},
|
||||
{"namespace", [](const func_args & args) -> value {
|
||||
auto out = mk_val<value_object>();
|
||||
for (const auto & arg : args.get_args()) {
|
||||
if (!is_val<value_kwarg>(arg)) {
|
||||
throw raised_exception("namespace() arguments must be kwargs");
|
||||
}
|
||||
auto kwarg = cast_val<value_kwarg>(arg);
|
||||
JJ_DEBUG("namespace: adding key '%s'", kwarg->key.c_str());
|
||||
out->insert(kwarg->key, kwarg->val);
|
||||
}
|
||||
return out;
|
||||
}},
|
||||
{"dict", toobject},
|
||||
{"namespace", toobject},
|
||||
{"strftime_now", [](const func_args & args) -> value {
|
||||
args.ensure_vals<value_string>();
|
||||
std::string format = args.get_pos(0)->as_string().str();
|
||||
|
||||
@@ -1976,6 +1976,30 @@ static void test_object_methods(testing & t) {
|
||||
json::object(),
|
||||
""
|
||||
);
|
||||
|
||||
test_template(t, "dict from dict",
|
||||
"{% set o = dict({'a': 3, 'b': 1, 'c': 2}) %}{{ o|tojson }}",
|
||||
json::object(),
|
||||
"{\"a\": 3, \"b\": 1, \"c\": 2}"
|
||||
);
|
||||
|
||||
test_template(t, "dict from kwargs",
|
||||
"{% set o = dict(a=3, b=1, c=2) %}{{ o|tojson }}",
|
||||
json::object(),
|
||||
"{\"a\": 3, \"b\": 1, \"c\": 2}"
|
||||
);
|
||||
|
||||
test_template(t, "dict from tuples",
|
||||
"{% set o = dict((obj | items | list)) %}{{ o|tojson }}",
|
||||
{{"obj", {{"a", 3}, {"b", 1}, {"c", 2}}}},
|
||||
"{\"a\": 3, \"b\": 1, \"c\": 2}"
|
||||
);
|
||||
|
||||
test_template(t, "dict from tuples and kwargs",
|
||||
"{% set o = dict((obj | items | list), c=2) %}{{ o|tojson }}",
|
||||
{{"obj", {{"a", 3}, {"b", 1}}}},
|
||||
"{\"a\": 3, \"b\": 1, \"c\": 2}"
|
||||
);
|
||||
}
|
||||
|
||||
static void test_hasher(testing & t) {
|
||||
|
||||
Reference in New Issue
Block a user