This commit is contained in:
William Fu-Hinthorn
2025-03-19 14:49:37 -07:00
parent 2f7f3b85c2
commit ee66e9165c
5 changed files with 45 additions and 101 deletions
+5 -37
View File
@@ -1287,7 +1287,7 @@ typing-extensions = ">=4.7"
[[package]]
name = "langgraph-checkpoint"
version = "2.0.18"
version = "2.0.21"
description = "Library with base interfaces for LangGraph checkpoint savers."
optional = false
python-versions = "^3.9.0,<4.0"
@@ -1304,7 +1304,7 @@ url = "../checkpoint"
[[package]]
name = "langgraph-checkpoint-postgres"
version = "2.0.16"
version = "2.0.18"
description = "Library with a Postgres implementation of LangGraph checkpoint saver."
optional = false
python-versions = "^3.9.0,<4.0"
@@ -1340,7 +1340,7 @@ url = "../checkpoint-sqlite"
[[package]]
name = "langgraph-prebuilt"
version = "0.1.2"
version = "0.1.3"
description = "Library with high-level APIs for creating and executing LangGraph agents and tools."
optional = false
python-versions = "^3.9.0,<4.0"
@@ -1357,7 +1357,7 @@ url = "../prebuilt"
[[package]]
name = "langgraph-sdk"
version = "0.1.55"
version = "0.1.58"
description = "SDK for interacting with LangGraph API"
optional = false
python-versions = "^3.9.0,<4.0"
@@ -1717,24 +1717,6 @@ files = [
{file = "nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe"},
]
[[package]]
name = "networkx"
version = "3.2.1"
description = "Python package for creating and manipulating graphs and networks"
optional = false
python-versions = ">=3.9"
files = [
{file = "networkx-3.2.1-py3-none-any.whl", hash = "sha256:f18c69adc97877c42332c170849c96cefa91881c99a7cb3e95b7c659ebdc1ec2"},
{file = "networkx-3.2.1.tar.gz", hash = "sha256:9f1bb5cf3409bf324e0a722c20bdb4c20ee39bf1c30ce8ae499c8502b0b5e0c6"},
]
[package.extras]
default = ["matplotlib (>=3.5)", "numpy (>=1.22)", "pandas (>=1.4)", "scipy (>=1.9,!=1.11.0,!=1.11.1)"]
developer = ["changelist (==0.4)", "mypy (>=1.1)", "pre-commit (>=3.2)", "rtoml"]
doc = ["nb2plots (>=0.7)", "nbconvert (<7.9)", "numpydoc (>=1.6)", "pillow (>=9.4)", "pydata-sphinx-theme (>=0.14)", "sphinx (>=7)", "sphinx-gallery (>=0.14)", "texext (>=0.6.7)"]
extra = ["lxml (>=4.6)", "pydot (>=1.4.2)", "pygraphviz (>=1.11)", "sympy (>=1.10)"]
test = ["pytest (>=7.2)", "pytest-cov (>=4.0)"]
[[package]]
name = "notebook"
version = "7.2.2"
@@ -2753,20 +2735,6 @@ files = [
attrs = ">=22.2.0"
rpds-py = ">=0.7.0"
[[package]]
name = "referrers"
version = "0.12.0"
description = "Finds the graph of referrers for a Python object"
optional = false
python-versions = ">=3.8"
files = [
{file = "referrers-0.12.0-py3-none-any.whl", hash = "sha256:a59a302b0d314f426cd309c0c4d0f1b66fd266a1c46784b590a0c067385a0276"},
{file = "referrers-0.12.0.tar.gz", hash = "sha256:47d37a7a53c086070c0751e825143feb008bac603c4cddf897d655db28804003"},
]
[package.dependencies]
networkx = ">=2.4"
[[package]]
name = "requests"
version = "2.32.3"
@@ -3425,4 +3393,4 @@ type = ["pytest-mypy"]
[metadata]
lock-version = "2.0"
python-versions = ">=3.9.0,<4.0"
content-hash = "ded968afc6be33e48198c04606493c161d27a44e1f11eeecf9be573ddb6b73b1"
content-hash = "b8641a0b2d92bee0363602e69f99b23366b2035b7e17ff017708194e6fbd0ac5"
-1
View File
@@ -38,7 +38,6 @@ pyperf = "^2.7.0"
py-spy = "^0.3.14"
types-requests = "^2.32.0.20240914"
pycryptodome = "^3.21.0"
referrers = "^0.12.0"
[tool.ruff]
lint.select = [ "E", "F", "I", "TID251" ]
+4 -5
View File
@@ -5,7 +5,6 @@ from typing import AsyncIterator, Optional
from uuid import UUID, uuid4
import pytest
import referrers
from langchain_core import __version__ as core_version
from packaging import version
from psycopg import AsyncConnection, Connection
@@ -452,10 +451,10 @@ async def awith_store(store_name: Optional[str]) -> AsyncIterator[BaseStore]:
@pytest.fixture(autouse=True)
def check_live_objects() -> None:
"""Check for live objects after each test."""
gc.collect()
gc.disable()
try:
yield
gc.disable()
# Should we be yielding?
gc.collect()
leaked_objs = [
o
for o in gc.get_objects()
@@ -470,7 +469,7 @@ def check_live_objects() -> None:
),
)
]
assert not leaked_objs, f"""Leaked objects at end of test: {referrers.get_referrer_graph_for_list(leaked_objs, exclude_object_ids=(id(leaked_objs),))}"""
assert not leaked_objs, f"{len(leaked_objs)} leaked objects at end of test."
finally:
gc.enable()
+18 -27
View File
@@ -7623,37 +7623,28 @@ def test_parallel_interrupts_double(
def test_pregel_loop_refcount():
gc.collect()
try:
gc.disable()
class State(TypedDict):
messages: Annotated[list, add_messages]
class State(TypedDict):
messages: Annotated[list, add_messages]
graph_builder = StateGraph(State)
graph_builder = StateGraph(State)
def chatbot(state: State):
return {"messages": [("ai", "HIYA")]}
def chatbot(state: State):
return {"messages": [("ai", "HIYA")]}
graph_builder.add_node("chatbot", chatbot)
graph_builder.set_entry_point("chatbot")
graph_builder.set_finish_point("chatbot")
graph = graph_builder.compile()
graph_builder.add_node("chatbot", chatbot)
graph_builder.set_entry_point("chatbot")
graph_builder.set_finish_point("chatbot")
graph = graph_builder.compile()
for _ in range(5):
graph.invoke({"messages": [{"role": "user", "content": "hi"}]})
assert (
len(
[obj for obj in gc.get_objects() if isinstance(obj, SyncPregelLoop)]
)
== 0
)
assert (
len([obj for obj in gc.get_objects() if isinstance(obj, PregelRunner)])
== 0
)
finally:
gc.enable()
for _ in range(5):
graph.invoke({"messages": [{"role": "user", "content": "hi"}]})
assert (
len([obj for obj in gc.get_objects() if isinstance(obj, SyncPregelLoop)])
== 0
)
assert (
len([obj for obj in gc.get_objects() if isinstance(obj, PregelRunner)]) == 0
)
@pytest.mark.parametrize("checkpointer_name", REGULAR_CHECKPOINTERS_SYNC)
+18 -31
View File
@@ -7848,41 +7848,28 @@ async def test_handles_multiple_interrupts_from_tasks() -> None:
async def test_pregel_loop_refcount():
gc.collect()
try:
gc.disable()
class State(TypedDict):
messages: Annotated[list, add_messages]
class State(TypedDict):
messages: Annotated[list, add_messages]
graph_builder = StateGraph(State)
graph_builder = StateGraph(State)
async def chatbot(state: State):
return {"messages": [("ai", "HIYA")]}
async def chatbot(state: State):
return {"messages": [("ai", "HIYA")]}
graph_builder.add_node("chatbot", chatbot)
graph_builder.set_entry_point("chatbot")
graph_builder.set_finish_point("chatbot")
graph = graph_builder.compile()
graph_builder.add_node("chatbot", chatbot)
graph_builder.set_entry_point("chatbot")
graph_builder.set_finish_point("chatbot")
graph = graph_builder.compile()
for _ in range(5):
await graph.ainvoke({"messages": [{"role": "user", "content": "hi"}]})
assert (
len(
[
obj
for obj in gc.get_objects()
if isinstance(obj, AsyncPregelLoop)
]
)
== 0
)
assert (
len([obj for obj in gc.get_objects() if isinstance(obj, PregelRunner)])
== 0
)
finally:
gc.enable()
for _ in range(5):
await graph.ainvoke({"messages": [{"role": "user", "content": "hi"}]})
assert (
len([obj for obj in gc.get_objects() if isinstance(obj, AsyncPregelLoop)])
== 0
)
assert (
len([obj for obj in gc.get_objects() if isinstance(obj, PregelRunner)]) == 0
)
@pytest.mark.parametrize("checkpointer_name", REGULAR_CHECKPOINTERS_ASYNC)