From 9c21d84bcbaf541d6aa9bcc28131bad3f4288c2d Mon Sep 17 00:00:00 2001 From: Lingjin <30501802+Haaaarry@users.noreply.github.com> Date: Tue, 18 Aug 2026 08:29:33 +0800 Subject: [PATCH] fix(core): accept non-dict Mapping values in mustache templates (#39680) --- libs/core/langchain_core/utils/mustache.py | 2 +- libs/core/tests/unit_tests/prompts/test_prompt.py | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/libs/core/langchain_core/utils/mustache.py b/libs/core/langchain_core/utils/mustache.py index 41d690330f..8d47b13f18 100644 --- a/libs/core/langchain_core/utils/mustache.py +++ b/libs/core/langchain_core/utils/mustache.py @@ -394,7 +394,7 @@ def _get_key( if resolved_scope in (0, False): return resolved_scope # Move into the scope - if isinstance(resolved_scope, dict): + if isinstance(resolved_scope, Mapping): try: resolved_scope = resolved_scope[child] except (KeyError, TypeError): diff --git a/libs/core/tests/unit_tests/prompts/test_prompt.py b/libs/core/tests/unit_tests/prompts/test_prompt.py index 9d084aeb55..ed7449fd7e 100644 --- a/libs/core/tests/unit_tests/prompts/test_prompt.py +++ b/libs/core/tests/unit_tests/prompts/test_prompt.py @@ -1,7 +1,9 @@ """Test functionality related to prompts.""" import re +from collections import ChainMap, UserDict from tempfile import NamedTemporaryFile +from types import MappingProxyType from typing import Any, Literal from unittest import mock @@ -251,6 +253,16 @@ def test_mustache_prompt_from_template(snapshot: SnapshotAssertion) -> None: } +def test_mustache_prompt_with_non_dict_mapping() -> None: + """Test mustache templates accept non-`dict` `Mapping` values.""" + template = "Hello {{user.name}}" + prompt = PromptTemplate.from_template(template, template_format="mustache") + + assert prompt.format(user=ChainMap({"name": "Alice"})) == "Hello Alice" + assert prompt.format(user=UserDict({"name": "Alice"})) == "Hello Alice" + assert prompt.format(user=MappingProxyType({"name": "Alice"})) == "Hello Alice" + + def test_prompt_from_template_with_partial_variables() -> None: """Test prompts can be constructed from a template with partial variables.""" # given