From 66e5378260fe3a84b1001f9888e24d6ec7f626b9 Mon Sep 17 00:00:00 2001 From: Michael Li Date: Sun, 2 Nov 2025 04:24:01 +1100 Subject: [PATCH 1/2] fix(core): fix data[key] edge case such as an empty string --- libs/core/langchain_core/utils/env.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/core/langchain_core/utils/env.py b/libs/core/langchain_core/utils/env.py index f19928e8761ab..8956a9f8e72ed 100644 --- a/libs/core/langchain_core/utils/env.py +++ b/libs/core/langchain_core/utils/env.py @@ -48,7 +48,7 @@ def get_from_dict_or_env( if value := data.get(k): return value - if isinstance(key, str) and key in data and data[key]: + if isinstance(key, str) and key in data and data[key] is not None: return data[key] key_for_err = key[0] if isinstance(key, (list, tuple)) else key From 70f80f8e6746c71f52bb0a7a70cb0a26044c5c74 Mon Sep 17 00:00:00 2001 From: Michael Li Date: Sun, 2 Nov 2025 14:32:48 +1100 Subject: [PATCH 2/2] fix(core): update for fix data[key] edge case such as an empty string --- libs/core/langchain_core/utils/env.py | 4 +-- libs/core/tests/unit_tests/utils/test_env.py | 28 ++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/libs/core/langchain_core/utils/env.py b/libs/core/langchain_core/utils/env.py index 8956a9f8e72ed..7d4d7e7ab5220 100644 --- a/libs/core/langchain_core/utils/env.py +++ b/libs/core/langchain_core/utils/env.py @@ -45,8 +45,8 @@ def get_from_dict_or_env( """ if isinstance(key, (list, tuple)): for k in key: - if value := data.get(k): - return value + if k in data and data[k] is not None: + return data[k] if isinstance(key, str) and key in data and data[key] is not None: return data[key] diff --git a/libs/core/tests/unit_tests/utils/test_env.py b/libs/core/tests/unit_tests/utils/test_env.py index 0d52e8534c68f..4d19da54ad32e 100644 --- a/libs/core/tests/unit_tests/utils/test_env.py +++ b/libs/core/tests/unit_tests/utils/test_env.py @@ -67,3 +67,31 @@ def test_get_from_dict_or_env() -> None: ) is None ) + + +def test_get_from_dict_or_env_empty_string() -> None: + """Test that empty strings are returned consistently for list and string keys.""" + data = {"key": "", "other": "value"} + + # Test single string key with empty string value + assert get_from_dict_or_env(data, "key", "ENV_KEY", default="default") == "" + + # Test list of keys with empty string value (should behave the same) + assert get_from_dict_or_env(data, ["key"], "ENV_KEY", default="default") == "" + + # Test list of keys where first key has empty string + result = get_from_dict_or_env(data, ["key", "other"], "ENV_KEY", default="default") + assert result == "" + + +def test_get_from_dict_or_env_none_value() -> None: + """Test that None values are skipped and default is used.""" + data = {"key": None, "other": "value"} + + # Test single string key with None value - should use default + result = get_from_dict_or_env(data, "key", "ENV_KEY", default="default") + assert result == "default" + + # Test list of keys with None value - should skip to next key + result = get_from_dict_or_env(data, ["key", "other"], "ENV_KEY", default="default") + assert result == "value"