From f7fae7e140c977a53ef2a7972e77c83cd7c938fd Mon Sep 17 00:00:00 2001 From: Vadym Barda Date: Tue, 14 Jan 2025 17:17:50 -0500 Subject: [PATCH] langgraph: fix ismethod check in add_node (#3032) Fixes #2893 #2965 --- libs/langgraph/langgraph/graph/state.py | 6 +++++- libs/langgraph/tests/test_state.py | 12 +++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/libs/langgraph/langgraph/graph/state.py b/libs/langgraph/langgraph/graph/state.py index d5e4a5480..7b950556b 100644 --- a/libs/langgraph/langgraph/graph/state.py +++ b/libs/langgraph/langgraph/graph/state.py @@ -361,7 +361,11 @@ class StateGraph(Graph): ends = EMPTY_SEQ try: - if (isfunction(action) or ismethod(getattr(action, "__call__", None))) and ( + if ( + isfunction(action) + or ismethod(action) + or ismethod(getattr(action, "__call__", None)) + ) and ( hints := get_type_hints(getattr(action, "__call__")) or get_type_hints(action) ): diff --git a/libs/langgraph/tests/test_state.py b/libs/langgraph/tests/test_state.py index 0a4a8725a..5af406669 100644 --- a/libs/langgraph/tests/test_state.py +++ b/libs/langgraph/tests/test_state.py @@ -79,11 +79,19 @@ def test_state_schema_with_type_hint(): def pre_foo(_) -> FooState: return {"foo": "bar"} + def pre_bar(_) -> FooState: + return {"foo": "bar"} + class Foo: def __call__(self, state: FooState) -> OutputState: assert state.pop("foo") == "bar" return {"input_state": state} + class Bar: + def my_node(self, state: FooState) -> OutputState: + assert state.pop("foo") == "bar" + return {"input_state": state} + graph = StateGraph(InputState, output=OutputState) actions = [ complete_hint, @@ -92,6 +100,8 @@ def test_state_schema_with_type_hint(): miss_all_hint, pre_foo, Foo(), + pre_bar, + Bar().my_node, ] for action in actions: @@ -112,7 +122,7 @@ def test_state_schema_with_type_hint(): foo_state = FooState(foo="bar") for i, c in enumerate(graph.stream(input_state, stream_mode="updates")): node_name = get_name(actions[i]) - if node_name == get_name(pre_foo): + if node_name in {"pre_foo", "pre_bar"}: assert c[node_name] == foo_state else: assert c[node_name] == output_state