diff --git a/libs/checkpoint-postgres/poetry.lock b/libs/checkpoint-postgres/poetry.lock index c6439bcb2..93cf19f28 100644 --- a/libs/checkpoint-postgres/poetry.lock +++ b/libs/checkpoint-postgres/poetry.lock @@ -187,22 +187,12 @@ description = "Cross-platform colored terminal text." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" groups = ["dev"] +markers = "sys_platform == \"win32\"" files = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] -[[package]] -name = "docopt" -version = "0.6.2" -description = "Pythonic argument parser, that will make you smile" -optional = false -python-versions = "*" -groups = ["dev"] -files = [ - {file = "docopt-0.6.2.tar.gz", hash = "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491"}, -] - [[package]] name = "exceptiongroup" version = "1.2.2" @@ -962,21 +952,20 @@ pytest = ">=6.2.5" dev = ["pre-commit", "pytest-asyncio", "tox"] [[package]] -name = "pytest-watch" -version = "4.2.0" -description = "Local continuous test runner with pytest and watchdog." +name = "pytest-watcher" +version = "0.4.3" +description = "Automatically rerun your tests on file modifications" optional = false -python-versions = "*" +python-versions = "<4.0.0,>=3.7.0" groups = ["dev"] files = [ - {file = "pytest-watch-4.2.0.tar.gz", hash = "sha256:06136f03d5b361718b8d0d234042f7b2f203910d8568f63df2f866b547b3d4b9"}, + {file = "pytest_watcher-0.4.3-py3-none-any.whl", hash = "sha256:d59b1e1396f33a65ea4949b713d6884637755d641646960056a90b267c3460f9"}, + {file = "pytest_watcher-0.4.3.tar.gz", hash = "sha256:0cb0e4661648c8c0ff2b2d25efa5a8e421784b9e4c60fcecbf9b7c30b2d731b3"}, ] [package.dependencies] -colorama = ">=0.3.3" -docopt = ">=0.4.0" -pytest = ">=2.6.4" -watchdog = ">=0.6.0" +tomli = {version = ">=2.0.1,<3.0.0", markers = "python_version < \"3.11\""} +watchdog = ">=2.0.0" [[package]] name = "pyyaml" @@ -1266,4 +1255,4 @@ watchmedo = ["PyYAML (>=3.10)"] [metadata] lock-version = "2.1" python-versions = "^3.9.0,<4.0" -content-hash = "61326e4e81a4e8854763a119f39d4f5d0a54cee868b4dbc91b95ce7d2cebba5b" +content-hash = "ca18ea480430714e47685ff0f25da9990dbbdecd38e9c1a3ca41d42be7069067" diff --git a/libs/checkpoint-postgres/pyproject.toml b/libs/checkpoint-postgres/pyproject.toml index 3bf01d676..869f802f3 100644 --- a/libs/checkpoint-postgres/pyproject.toml +++ b/libs/checkpoint-postgres/pyproject.toml @@ -22,10 +22,10 @@ pytest = "^7.2.1" anyio = "^4.4.0" pytest-asyncio = "^0.21.1" pytest-mock = "^3.11.1" -pytest-watch = "^4.2.0" mypy = "^1.10.0" psycopg = {extras = ["binary"], version = ">=3.0.0"} langgraph-checkpoint = {path = "../checkpoint", develop = true} +pytest-watcher = "^0.4.3" [tool.pytest.ini_options] # --strict-markers will raise errors on unknown marks. @@ -61,3 +61,9 @@ warn_unused_ignores = "True" warn_redundant_casts = "True" allow_redefinition = "True" disable_error_code = "typeddict-item, return-value" + +[tool.pytest-watcher] +now = true +delay = 0.1 +runner_args = ["--ff", "-x", "-v", "--tb", "short"] +patterns = ["*.py"] diff --git a/libs/checkpoint-postgres/tests/test_async.py b/libs/checkpoint-postgres/tests/test_async.py index 8c54e5787..2beffb3a5 100644 --- a/libs/checkpoint-postgres/tests/test_async.py +++ b/libs/checkpoint-postgres/tests/test_async.py @@ -11,6 +11,7 @@ from psycopg.rows import dict_row from psycopg_pool import AsyncConnectionPool from langgraph.checkpoint.base import ( + EXCLUDED_METADATA_KEYS, Checkpoint, CheckpointMetadata, create_checkpoint, @@ -23,6 +24,10 @@ from langgraph.checkpoint.postgres.aio import ( from tests.conftest import DEFAULT_POSTGRES_URI +def _exclude_keys(config: dict[str, Any]) -> dict[str, Any]: + return {k: v for k, v in config.items() if k not in EXCLUDED_METADATA_KEYS} + + @asynccontextmanager async def _pool_saver(): """Fixture for pool mode testing.""" @@ -223,7 +228,6 @@ async def test_combined_metadata(saver_name: str, test_data) -> None: assert checkpoint.metadata == { **metadata, "thread_id": "thread-2", - "checkpoint_ns": "", "run_id": "my_run_id", } @@ -251,14 +255,14 @@ async def test_asearch(saver_name: str, test_data) -> None: search_results_1 = [c async for c in saver.alist(None, filter=query_1)] assert len(search_results_1) == 1 assert search_results_1[0].metadata == { - **configs[0]["configurable"], + **_exclude_keys(configs[0]["configurable"]), **metadata[0], } search_results_2 = [c async for c in saver.alist(None, filter=query_2)] assert len(search_results_2) == 1 assert search_results_2[0].metadata == { - **configs[1]["configurable"], + **_exclude_keys(configs[1]["configurable"]), **metadata[1], } diff --git a/libs/checkpoint-postgres/tests/test_sync.py b/libs/checkpoint-postgres/tests/test_sync.py index e0e60a938..b78f38e9a 100644 --- a/libs/checkpoint-postgres/tests/test_sync.py +++ b/libs/checkpoint-postgres/tests/test_sync.py @@ -12,6 +12,7 @@ from psycopg.rows import dict_row from psycopg_pool import ConnectionPool from langgraph.checkpoint.base import ( + EXCLUDED_METADATA_KEYS, Checkpoint, CheckpointMetadata, create_checkpoint, @@ -21,6 +22,10 @@ from langgraph.checkpoint.postgres import PostgresSaver, ShallowPostgresSaver from tests.conftest import DEFAULT_POSTGRES_URI +def _exclude_keys(config: dict[str, Any]) -> dict[str, Any]: + return {k: v for k, v in config.items() if k not in EXCLUDED_METADATA_KEYS} + + @contextmanager def _pool_saver(): """Fixture for pool mode testing.""" @@ -205,7 +210,6 @@ def test_combined_metadata(saver_name: str, test_data) -> None: assert checkpoint.metadata == { **metadata, "thread_id": "thread-2", - "checkpoint_ns": "", "run_id": "my_run_id", } @@ -233,14 +237,14 @@ def test_search(saver_name: str, test_data) -> None: search_results_1 = list(saver.list(None, filter=query_1)) assert len(search_results_1) == 1 assert search_results_1[0].metadata == { - **configs[0]["configurable"], + **_exclude_keys(configs[0]["configurable"]), **metadata[0], } search_results_2 = list(saver.list(None, filter=query_2)) assert len(search_results_2) == 1 assert search_results_2[0].metadata == { - **configs[1]["configurable"], + **_exclude_keys(configs[1]["configurable"]), **metadata[1], } diff --git a/libs/checkpoint/langgraph/store/base/batch.py b/libs/checkpoint/langgraph/store/base/batch.py index 1bf2ac79e..debf187b3 100644 --- a/libs/checkpoint/langgraph/store/base/batch.py +++ b/libs/checkpoint/langgraph/store/base/batch.py @@ -59,7 +59,10 @@ class AsyncBatchedBaseStore(BaseStore): self._task = self._loop.create_task(_run(self._aqueue, weakref.ref(self))) def __del__(self) -> None: - self._task.cancel() + try: + self._task.cancel() + except RuntimeError: + pass async def aget( self,