Skip to content

fix(types): normalise Function.args/kwargs None to [] / {} in __post_init__#484

Open
SuperMarioYL wants to merge 1 commit into
SylphAI-Inc:mainfrom
SuperMarioYL:bugfix/function-args-kwargs-none-unpack
Open

fix(types): normalise Function.args/kwargs None to [] / {} in __post_init__#484
SuperMarioYL wants to merge 1 commit into
SylphAI-Inc:mainfrom
SuperMarioYL:bugfix/function-args-kwargs-none-unpack

Conversation

@SuperMarioYL
Copy link
Copy Markdown

Summary

Fixes #479.

Function declares args and kwargs as Optional[List] / Optional[Dict] with default_factory=list / default_factory=dict. The defaults only apply when a field is omitted; an explicit None (which JsonOutputParser produces when the LLM omits or nullifies a field) bypasses the factory and stores None directly. Any subsequent unpack (*func.args, **func.kwargs) then raises:

TypeError: argument after * must be an iterable, not NoneType

This crash affects every call site that unpacks func.args/func.kwargsToolManager.execute_func, ToolManager.execute_func_async, CallFunctionTool.call, and PermissionManager.

Fix

Add Function.__post_init__ (calling super().__post_init__() to keep base-class metadata validation) that normalises None → [] for args and None → {} for kwargs. All existing and future call sites are protected without per-site guard code.

def __post_init__(self):
    super().__post_init__()
    if self.args is None:
        self.args = []
    if self.kwargs is None:
        self.kwargs = {}

Tests

Five new tests added to adalflow/tests/test_tool.py:

Test What it checks
test_function_none_args_normalised_to_empty_list Function(args=None) stores []
test_function_none_kwargs_normalised_to_empty_dict Function(kwargs=None) stores {}
test_function_both_none_normalised Both None at once
test_function_tool_call_with_none_args_does_not_raise tool.call(*func.args, **func.kwargs) doesn't crash
test_tool_manager_execute_func_with_none_args ToolManager.execute_func round-trip

All 29 tests in test_tool.py pass (24 pre-existing + 5 new).

…init__

When a JsonOutputParser schema emits "required": [] for Function, LLMs may
omit args or kwargs entirely; the deserialiser then sets those fields to None.
Any subsequent *func.args or **func.kwargs unpack raises TypeError.

Add __post_init__ to Function that converts None → [] for args and None → {}
for kwargs so every call site is safe without per-site guard code.

Fixes SylphAI-Inc#479
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TypeError: argument after * must be an iterable, not NoneType — Function.args/kwargs typed Optional but unpacked unconditionally

1 participant