Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-langgraph for 
openSUSE:Factory checked in at 2026-10-26 10:03:07
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-langgraph (Old)
 and      /work/SRC/openSUSE:Factory/.python-langgraph.new.2252680 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-langgraph"

Mon Oct 26 10:03:07 2026 rev:12 rq:1392568 version:1.2.17

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-langgraph/python-langgraph.changes        
2026-10-17 21:27:00.553902447 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-langgraph.new.2252680/python-langgraph.changes
   2026-10-26 10:04:32.855150510 +0100
@@ -1,0 +2,9 @@
+Sun Oct 25 06:00:00 UTC 2026 - Martin Pluskal <[email protected]>
+
+- Update to 1.2.17:
+  * Apply an explicit recursion_limit equal to the default
+  * Keep the caller's namespace in RemoteGraph.stream
+    with subgraphs
+  * Drop precautionary third-party upper bounds
+
+-------------------------------------------------------------------

Old:
----
  langgraph-1.2.16.tar.gz

New:
----
  langgraph-1.2.17.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-langgraph.spec ++++++
--- /var/tmp/diff_new_pack.6ege1h/_old  2026-10-26 10:04:33.912194822 +0100
+++ /var/tmp/diff_new_pack.6ege1h/_new  2026-10-26 10:04:33.915194948 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           python-langgraph
-Version:        1.2.16
+Version:        1.2.17
 Release:        0
 Summary:        Library for building stateful, multi-actor applications with 
LLMs
 License:        MIT

++++++ langgraph-1.2.16.tar.gz -> langgraph-1.2.17.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/langgraph-1.2.16/Makefile 
new/langgraph-1.2.17/Makefile
--- old/langgraph-1.2.16/Makefile       2020-02-02 01:00:00.000000000 +0100
+++ new/langgraph-1.2.17/Makefile       2020-02-02 01:00:00.000000000 +0100
@@ -43,14 +43,31 @@
 stop-services:
        docker compose -f tests/compose-postgres.yml -f tests/compose-redis.yml 
down -v
 
+DEV_SERVER_PYTHON ?= 3.12
+DEV_SERVER_ENV = $(CURDIR)/.venvs/dev-server
+
 start-dev-server:
-       LOG_LEVEL=warning uv run langgraph dev --config 
tests/example_app/langgraph.json --no-browser & echo "$$!" > .devserver.pid
-       @echo "Dev server started."
+       uv sync --frozen --group test --no-dev
+       UV_PROJECT_ENVIRONMENT=$(DEV_SERVER_ENV) uv sync --frozen --group test 
--no-dev --python $(DEV_SERVER_PYTHON)
+       @LOG_LEVEL=warning UV_PROJECT_ENVIRONMENT=$(DEV_SERVER_ENV) uv run 
--no-sync --python $(DEV_SERVER_PYTHON) langgraph dev --config 
tests/example_app/langgraph.json --no-browser --no-reload & \
+       PID=$$!; echo "$$PID" > .devserver.pid; \
+       for ATTEMPT in $$(seq 1 60); do \
+               if ! kill -0 $$PID 2>/dev/null; then break; fi; \
+               if curl --fail --silent --max-time 1 http://localhost:2024/ok 
>/dev/null; then \
+                       echo "Dev server ready."; exit 0; \
+               fi; \
+               sleep 1; \
+       done; \
+       echo "Dev server failed to become ready." >&2; \
+       kill $$PID 2>/dev/null || true; \
+       wait $$PID 2>/dev/null || true; \
+       rm -f .devserver.pid; exit 1
 
 stop-dev-server:
        @if [ -f .devserver.pid ]; then \
-               kill `cat .devserver.pid` && rm .devserver.pid; \
-                echo "Dev server stopped."; \
+               kill $$(cat .devserver.pid) 2>/dev/null || true; \
+               rm -f .devserver.pid; \
+               echo "Dev server stopped."; \
        else \
                echo "No dev server PID file found."; \
        fi
@@ -60,13 +77,12 @@
 
 test:
        if [ "$(NO_DOCKER)" = "false" ]; then \
-               make start-services &&\
-               make start-dev-server &&\
-               uv run pytest $(TEST); \
-               EXIT_CODE=$$?; \
-               make stop-services; \
-               make stop-dev-server; \
-               exit $$EXIT_CODE; \
+               trap '$(MAKE) stop-dev-server; $(MAKE) stop-services' EXIT; \
+               trap 'exit 130' INT; trap 'exit 143' TERM; \
+               $(MAKE) start-services &&\
+               $(MAKE) start-dev-server &&\
+               uv run --no-sync pytest $(TEST); \
+               exit $$?; \
        else \
                NO_DOCKER=true uv run pytest $(TEST) ; \
                EXIT_CODE=$$?; \
@@ -74,13 +90,12 @@
        fi
 
 test_parallel:
-       make start-services &&\
-       make start-dev-server &&\
-       uv run pytest -n auto --dist worksteal $(TEST) -vv --lf; \
-       EXIT_CODE=$$?; \
-       make stop-services; \
-       make stop-dev-server; \
-       exit $$EXIT_CODE
+       trap '$(MAKE) stop-dev-server; $(MAKE) stop-services' EXIT; \
+       trap 'exit 130' INT; trap 'exit 143' TERM; \
+       $(MAKE) start-services &&\
+       $(MAKE) start-dev-server &&\
+       uv run --no-sync pytest -n auto --dist worksteal $(TEST) -vv --lf; \
+       exit $$?
 
 integration_tests:
        uv run pytest integration_tests
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/langgraph-1.2.16/PKG-INFO 
new/langgraph-1.2.17/PKG-INFO
--- old/langgraph-1.2.16/PKG-INFO       2020-02-02 01:00:00.000000000 +0100
+++ new/langgraph-1.2.17/PKG-INFO       2020-02-02 01:00:00.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.5
 Name: langgraph
-Version: 1.2.16
+Version: 1.2.17
 Summary: Building stateful, multi-actor applications with LLMs
 Project-URL: Homepage, https://docs.langchain.com/oss/python/langgraph/overview
 Project-URL: Documentation, https://reference.langchain.com/python/langgraph/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/langgraph-1.2.16/langgraph/_internal/_config.py 
new/langgraph-1.2.17/langgraph/_internal/_config.py
--- old/langgraph-1.2.16/langgraph/_internal/_config.py 2020-02-02 
01:00:00.000000000 +0100
+++ new/langgraph-1.2.17/langgraph/_internal/_config.py 2020-02-02 
01:00:00.000000000 +0100
@@ -29,7 +29,19 @@
     NS_SEP,
 )
 
-DEFAULT_RECURSION_LIMIT = int(getenv("LANGGRAPH_DEFAULT_RECURSION_LIMIT", 
"10007"))
+
+class _DefaultRecursionLimit(int):
+    """The limit `ensure_config` fills in when none is given.
+
+    `merge_configs` skips values of this type rather than any equal value, so 
an
+    explicit limit that happens to equal the default still applies. It checks 
the
+    type, not identity, because copying or pickling a config rebuilds the 
value.
+    """
+
+
+DEFAULT_RECURSION_LIMIT = _DefaultRecursionLimit(
+    getenv("LANGGRAPH_DEFAULT_RECURSION_LIMIT", "10007")
+)
 DELTA_MAX_SUPERSTEPS_SINCE_SNAPSHOT = int(
     getenv("LANGGRAPH_DELTA_MAX_SUPERSTEPS_SINCE_SNAPSHOT", "5000")
 )
@@ -182,7 +194,7 @@
                     base.get("callbacks"), cast(Callbacks, value)
                 )
             elif key == "recursion_limit":
-                if config["recursion_limit"] != DEFAULT_RECURSION_LIMIT:
+                if not isinstance(config["recursion_limit"], 
_DefaultRecursionLimit):
                     base["recursion_limit"] = config["recursion_limit"]
             else:
                 base[key] = config[key]  # type: ignore[literal-required]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/langgraph-1.2.16/langgraph/pregel/remote.py 
new/langgraph-1.2.17/langgraph/pregel/remote.py
--- old/langgraph-1.2.16/langgraph/pregel/remote.py     2020-02-02 
01:00:00.000000000 +0100
+++ new/langgraph-1.2.17/langgraph/pregel/remote.py     2020-02-02 
01:00:00.000000000 +0100
@@ -861,11 +861,6 @@
                     )
                 yield {"type": mode, "ns": ns, "data": chunk.data, 
"interrupts": ints}
             elif subgraphs:
-                if NS_SEP in chunk.event:
-                    mode, ns_ = chunk.event.split(NS_SEP, 1)
-                    ns = tuple(ns_.split(NS_SEP))
-                else:
-                    mode, ns = chunk.event, ()
                 if req_single:
                     yield ns, chunk.data
                 else:
@@ -1016,11 +1011,6 @@
                     )
                 yield {"type": mode, "ns": ns, "data": chunk.data, 
"interrupts": ints}
             elif subgraphs:
-                if NS_SEP in chunk.event:
-                    mode, ns_ = chunk.event.split(NS_SEP, 1)
-                    ns = tuple(ns_.split(NS_SEP))
-                else:
-                    mode, ns = chunk.event, ()
                 if req_single:
                     yield ns, chunk.data
                 else:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/langgraph-1.2.16/pyproject.toml 
new/langgraph-1.2.17/pyproject.toml
--- old/langgraph-1.2.16/pyproject.toml 2020-02-02 01:00:00.000000000 +0100
+++ new/langgraph-1.2.17/pyproject.toml 2020-02-02 01:00:00.000000000 +0100
@@ -4,7 +4,7 @@
 
 [project]
 name = "langgraph"
-version = "1.2.16"
+version = "1.2.17"
 description = "Building stateful, multi-actor applications with LLMs"
 authors = []
 requires-python = ">=3.10"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/langgraph-1.2.16/tests/test_config_async.py 
new/langgraph-1.2.17/tests/test_config_async.py
--- old/langgraph-1.2.16/tests/test_config_async.py     2020-02-02 
01:00:00.000000000 +0100
+++ new/langgraph-1.2.17/tests/test_config_async.py     2020-02-02 
01:00:00.000000000 +0100
@@ -1,11 +1,19 @@
+from collections.abc import Callable
+
 import pytest
 from langchain_core.callbacks import AsyncCallbackManager, BaseCallbackHandler
 
-from langgraph._internal._config import get_async_callback_manager_for_config
+from langgraph._internal._config import (
+    DEFAULT_RECURSION_LIMIT,
+    get_async_callback_manager_for_config,
+)
 from langgraph.graph import StateGraph
+from langgraph.pregel import Pregel
 
 pytestmark = pytest.mark.anyio
 
+EXPLICIT_DEFAULT_LIMIT = int(DEFAULT_RECURSION_LIMIT)
+
 
 def test_new_async_manager_includes_tags() -> None:
     config = {"callbacks": None}
@@ -114,3 +122,27 @@
     await graph.ainvoke({}, {"tags": ["invoke"]})
     assert "bound" in captured, "bound tag was dropped by ensure_config 
overwrite"
     assert "invoke" in captured, "invoke-time tag not present"
+
+
[email protected](
+    "rebind",
+    [
+        lambda g: g.with_config(recursion_limit=EXPLICIT_DEFAULT_LIMIT),
+        lambda g: g.with_config({"recursion_limit": EXPLICIT_DEFAULT_LIMIT}),
+        lambda g: g.with_config(
+            {"recursion_limit": 1}, recursion_limit=EXPLICIT_DEFAULT_LIMIT
+        ),
+        lambda g: 
g.with_config(recursion_limit=EXPLICIT_DEFAULT_LIMIT).with_config(
+            tags=["t"]
+        ),
+    ],
+    ids=["kwarg", "config", "kwarg_over_config", "kept_by_later_with_config"],
+)
+def test_with_config_applies_recursion_limit_equal_to_default(
+    rebind: Callable[[Pregel], Pregel],
+) -> None:
+    builder = StateGraph(dict)
+    builder.add_node("node", lambda state: state)
+    builder.add_edge("__start__", "node")
+    graph = 
builder.compile().with_config(recursion_limit=EXPLICIT_DEFAULT_LIMIT + 1)
+    assert rebind(graph).config["recursion_limit"] == EXPLICIT_DEFAULT_LIMIT
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/langgraph-1.2.16/tests/test_prune_postgres.py 
new/langgraph-1.2.17/tests/test_prune_postgres.py
--- old/langgraph-1.2.16/tests/test_prune_postgres.py   2020-02-02 
01:00:00.000000000 +0100
+++ new/langgraph-1.2.17/tests/test_prune_postgres.py   2020-02-02 
01:00:00.000000000 +0100
@@ -2,6 +2,7 @@
 import sys
 from collections.abc import Callable
 from contextlib import contextmanager
+from threading import Event
 from typing import Annotated, Any
 
 import pytest
@@ -72,12 +73,15 @@
     ask: bool = False,
     fail: set[str] | None = None,
     calls: dict[str, int] | None = None,
+    before_fail: Callable[[], None] | None = None,
 ) -> Any:
     def note(name: str):
         def node(state: State) -> dict:
             if calls is not None:
                 calls[name] = calls.get(name, 0) + 1
             if fail is not None and name in fail:
+                if before_fail is not None:
+                    before_fail()
                 fail.discard(name)
                 raise ValueError(f"{name} failed")
             return {"notes": [name]}
@@ -234,18 +238,37 @@
 
 @pytest.mark.parametrize("make_checkpointer", SYNC)
 def test_keep_latest_keeps_writes_of_tasks_that_finished_before_a_failure(
-    make_checkpointer: Any,
+    make_checkpointer: Any, monkeypatch: pytest.MonkeyPatch
 ) -> None:
     with make_checkpointer() as checkpointer:
         calls: dict[str, int] = {}
         fail: set[str] = set()
-        graph = _graph(checkpointer, fail=fail, calls=calls)
+        left_persisted = Event()
+        put_writes = checkpointer.put_writes
+
+        def persist(config, writes, task_id, task_path=""):
+            put_writes(config, writes, task_id, task_path)
+            if ("notes", ["left"]) in writes:
+                left_persisted.set()
+
+        def wait_for_left() -> None:
+            assert left_persisted.wait(5), "left task writes were not 
persisted"
+
+        monkeypatch.setattr(checkpointer, "put_writes", persist)
+        graph = _graph(checkpointer, fail=fail, calls=calls, 
before_fail=wait_for_left)
         for thread_id in ("pruned", "twin"):
             for i in range(2):
                 graph.invoke(_say(i), _config(thread_id))
+            left_persisted.clear()
             fail.add("right")
             with pytest.raises(ValueError, match="right failed"):
                 graph.invoke(_say(2), _config(thread_id))
+            checkpoint = checkpointer.get_tuple(_config(thread_id))
+            assert checkpoint is not None
+            assert any(
+                channel == "notes" and value == ["left"]
+                for _, channel, value in checkpoint.pending_writes
+            )
         before = graph.get_state(_config("pruned"))
 
         checkpointer.prune(["pruned"])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/langgraph-1.2.16/tests/test_remote_graph.py 
new/langgraph-1.2.17/tests/test_remote_graph.py
--- old/langgraph-1.2.16/tests/test_remote_graph.py     2020-02-02 
01:00:00.000000000 +0100
+++ new/langgraph-1.2.17/tests/test_remote_graph.py     2020-02-02 
01:00:00.000000000 +0100
@@ -819,6 +819,50 @@
     ]
 
 
+_CALLER_CONFIG: RunnableConfig = {
+    "configurable": {"thread_id": "thread_1", "checkpoint_ns": "outer:123"}
+}
+_SUBGRAPH_PARTS = [
+    StreamPart(event="values|sub:abc", data={"chunk": "inner"}),
+    StreamPart(event="values", data={"chunk": "root"}),
+]
+_CALLER_PREFIXED = [
+    (("outer:123", "sub:abc"), {"chunk": "inner"}),
+    (("outer:123",), {"chunk": "root"}),
+]
+
+
+def test_stream_subgraphs_keeps_caller_namespace():
+    mock_sync_client = MagicMock()
+    mock_sync_client.runs.stream.return_value = _SUBGRAPH_PARTS
+    remote_pregel = RemoteGraph("test_graph_id", sync_client=mock_sync_client)
+
+    stream_parts = list(
+        remote_pregel.stream(
+            {"input": "data"}, _CALLER_CONFIG, stream_mode="values", 
subgraphs=True
+        )
+    )
+
+    assert stream_parts == _CALLER_PREFIXED
+
+
+async def test_astream_subgraphs_keeps_caller_namespace():
+    mock_async_client = MagicMock()
+    async_iter = MagicMock()
+    async_iter.__aiter__.return_value = _SUBGRAPH_PARTS
+    mock_async_client.runs.stream.return_value = async_iter
+    remote_pregel = RemoteGraph("test_graph_id", client=mock_async_client)
+
+    stream_parts = [
+        part
+        async for part in remote_pregel.astream(
+            {"input": "data"}, _CALLER_CONFIG, stream_mode="values", 
subgraphs=True
+        )
+    ]
+
+    assert stream_parts == _CALLER_PREFIXED
+
+
 def test_invoke():
     # set up test
     mock_sync_client = MagicMock()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/langgraph-1.2.16/tests/test_utils.py 
new/langgraph-1.2.17/tests/test_utils.py
--- old/langgraph-1.2.16/tests/test_utils.py    2020-02-02 01:00:00.000000000 
+0100
+++ new/langgraph-1.2.17/tests/test_utils.py    2020-02-02 01:00:00.000000000 
+0100
@@ -1,4 +1,6 @@
+import copy
 import functools
+import pickle
 import sys
 import uuid
 from collections.abc import Callable
@@ -25,6 +27,7 @@
 from typing_extensions import NotRequired, Required, TypedDict
 
 from langgraph._internal._config import (
+    DEFAULT_RECURSION_LIMIT,
     _is_not_empty,
     _merge_callbacks,
     ensure_config,
@@ -620,6 +623,30 @@
     assert merged["metadata"]["lc_agent_name"] == "agent"
 
 
[email protected](
+    "rebuild",
+    [
+        lambda config: config,
+        copy.deepcopy,
+        lambda config: pickle.loads(pickle.dumps(config)),
+    ],
+    ids=["as_is", "deepcopy", "pickle"],
+)
+def test_merge_configs_skips_the_injected_default_recursion_limit(
+    rebuild: Callable[[RunnableConfig], RunnableConfig],
+) -> None:
+    merged = merge_configs({"recursion_limit": 50}, rebuild(ensure_config()))
+    assert merged["recursion_limit"] == 50
+
+
+def test_merge_configs_applies_an_explicit_recursion_limit_equal_to_default() 
-> None:
+    explicit_default = int(DEFAULT_RECURSION_LIMIT)
+    merged = merge_configs(
+        {"recursion_limit": 50}, {"recursion_limit": explicit_default}
+    )
+    assert merged["recursion_limit"] == explicit_default
+
+
 def test_ensure_config_merges_metadata_lc_versions() -> None:
     a = {
         "metadata": {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/langgraph-1.2.16/uv.lock new/langgraph-1.2.17/uv.lock
--- old/langgraph-1.2.16/uv.lock        2020-02-02 01:00:00.000000000 +0100
+++ new/langgraph-1.2.17/uv.lock        2020-02-02 01:00:00.000000000 +0100
@@ -202,11 +202,11 @@
 
 [[package]]
 name = "certifi"
-version = "2026.1.4"
+version = "2026.10.19"
 source = { registry = "https://pypi.org/simple"; }
-sdist = { url = 
"https://files.pythonhosted.org/packages/e0/2d/a891ca51311197f6ad14a7ef42e2399f36cf2f9bd44752b3dc4eab60fdc5/certifi-2026.1.4.tar.gz";,
 hash = 
"sha256:ac726dd470482006e014ad384921ed6438c457018f4b3d204aea4281258b2120", size 
= 154268, upload-time = "2026-01-04T02:42:41.825Z" }
+sdist = { url = 
"https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz";,
 hash = 
"sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size 
= 137598, upload-time = "2026-10-20T02:24:16.604Z" }
 wheels = [
-    { url = 
"https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl";,
 hash = 
"sha256:9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c", size 
= 152900, upload-time = "2026-01-04T02:42:40.15Z" },
+    { url = 
"https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl";,
 hash = 
"sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size 
= 136464, upload-time = "2026-10-20T02:24:15.072Z" },
 ]
 
 [[package]]
@@ -1451,7 +1451,7 @@
 
 [[package]]
 name = "langgraph"
-version = "1.2.16"
+version = "1.2.17"
 source = { editable = "." }
 dependencies = [
     { name = "langchain-core" },
@@ -1856,7 +1856,7 @@
     { name = "langgraph-checkpoint", editable = "../checkpoint" },
     { name = "langgraph-checkpoint-postgres", editable = 
"../checkpoint-postgres" },
     { name = "langgraph-checkpoint-sqlite", editable = "../checkpoint-sqlite" 
},
-    { name = "psycopg-binary" },
+    { name = "psycopg", extras = ["binary"] },
     { name = "pytest" },
     { name = "pytest-asyncio" },
     { name = "pytest-mock" },
@@ -1876,7 +1876,7 @@
     { name = "langgraph-checkpoint", editable = "../checkpoint" },
     { name = "langgraph-checkpoint-postgres", editable = 
"../checkpoint-postgres" },
     { name = "langgraph-checkpoint-sqlite", editable = "../checkpoint-sqlite" 
},
-    { name = "psycopg-binary" },
+    { name = "psycopg", extras = ["binary"] },
     { name = "pytest" },
     { name = "pytest-asyncio" },
     { name = "pytest-mock" },
@@ -1919,7 +1919,7 @@
     { name = "langchain-core", specifier = ">=1.4.0,<2" },
     { name = "langchain-protocol", specifier = ">=0.0.15" },
     { name = "orjson", specifier = ">=3.11.5" },
-    { name = "websockets", specifier = ">=14,<17" },
+    { name = "websockets", specifier = ">=14" },
 ]
 
 [package.metadata.requires-dev]

Reply via email to