Python: Fix FunctionResult.__str__ rendering falsy values (0, False, 0.0) as empty string#14162
Python: Fix FunctionResult.__str__ rendering falsy values (0, False, 0.0) as empty string#14162sohumt123 wants to merge 1 commit into
Conversation
…0.0) as empty string
FunctionResult.__str__ used a truthiness check (if self.value:) where a
None-check was intended, so kernel functions returning falsy-but-meaningful
scalars (0, 0.0, False) rendered as an empty string when interpolated into
a prompt template, silently corrupting the prompt sent to the model.
Change the check to 'if self.value is not None:' and add explicit guards
for empty list/dict values so they still render as an empty string (an
empty dict would otherwise raise FunctionResultError when indexing).
Adds unit tests for 0, 0.0, False, '', [], {} and a KernelPromptTemplate
render test covering falsy function results.
|
@sohumt123 please read the following Contributor License Agreement(CLA). If you agree with the CLA, please reply with the following information.
Contributor License AgreementContribution License AgreementThis Contribution License Agreement (“Agreement”) is agreed to by the party signing below (“You”),
|
There was a problem hiding this comment.
Pull request overview
Fixes FunctionResult.__str__ so legitimate falsy return values (e.g., 0, 0.0, False) are rendered correctly instead of being treated as “empty”, preventing silent prompt corruption when results are interpolated into templates.
Changes:
- Update
FunctionResult.__str__to use aNonecheck (is not None) rather than a truthiness check. - Add safe handling for empty
listanddictvalues now that they pass theNoneguard. - Add unit coverage for falsy values and an integration-style prompt-template render assertion.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| python/semantic_kernel/functions/function_result.py | Correct __str__ guard to preserve falsy scalar values; add empty list/dict guards to avoid indexing errors. |
| python/tests/unit/functions/test_function_result.py | Add parametrized tests covering falsy scalars and empty containers for FunctionResult.__str__. |
| python/tests/unit/prompt_template/test_kernel_prompt_template.py | Add a render test proving falsy function outputs are preserved in template interpolation. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@microsoft-github-policy-service agree |
Motivation and Context
FunctionResult.__str__starts with a truthiness check (if self.value:) where aNone-check was intended. Any kernel function that legitimately returns a falsy scalar —0,0.0, orFalse— is rendered as an empty string whereverstr(FunctionResult)is used, most visibly when the result is interpolated into a prompt template via{{plugin.function ...}}(CodeBlock.render_code).Example: with a plugin whose functions return
5 - 5and3 % 2 == 0, the templaterenders as
The result is: and even=instead ofThe result is: 0 and even=False— the prompt sent to the model is silently corrupted with no warning or error. The same conflation affects logging and any other consumer ofstr(FunctionResult).Description
FunctionResult.__str__fromif self.value:toif self.value is not None:so falsy-but-meaningful values (0,0.0,False) render correctly.listanddictbranches, which are now reachable with empty containers:[]renders as""(previously it would indexself.value[0]), and{}renders as""(previouslylist(self.value.values())[-1]would raiseFunctionResultError).value=Noneandvalue=""is unchanged (both still render as""), preserving the existingtest_function_result_str_empty_valuecontract.main): parametrized unit tests for0,0.0,False,"",[],{}intest_function_result.py, plus aKernelPromptTemplaterender test intest_kernel_prompt_template.pyassertingThe result is: 0 and even=False.Verified locally:
uv run --frozen pytest tests/unit/functions/test_function_result.py tests/unit/functions/test_kernel_function_from_method.py tests/unit/prompt_template tests/unit/template_engine→ 729 passed;ruff check/ruff format --check/mypyclean on the touched files.Contribution Checklist