Repository navigation
Refresh the dependency lock, drop dependencies nothing needs, and move ruff to 0.16 - #1646
Conversation
The lock had drifted far behind: 30 of the 52 direct dependencies were behind their latest release, some by a major version. Refreshing it moves 112 locked packages, adds 6 and removes 2, with no downgrades. Nine are major bumps: complexipy 6 -> 8, cryptography 49 -> 50, fastmcp 3 -> 4 (and fastmcp-slim), mcp 1 -> 2, sentence-transformers 5 -> 6, setuptools 83 -> 84, websockets 16 -> 17, xxhash 3 -> 4. Direct dependencies that moved include fastapi 0.139.0 -> 0.141.1, instructor 1.15.4 -> 1.17.0, langchain-aws 1.6.2 -> 1.7.6, neo4j 6.2.0 -> 6.3.1, openai 2.45.0 -> 2.54.0, qdrant-client 1.18.0 -> 1.19.0, sqlalchemy 2.0.51 -> 2.0.53, ty 0.0.59 -> 0.0.81 and uvicorn 0.51.0 -> 0.53.0. Two specifiers had to change for the refresh to be honest: - litellm was capped at <1.85 when the provider was added (MemMachine#1386, which records no reason for the bound), and dependabot later widened it to <1.86. That range ends inside a stretch of releases -- 1.83.8 through 1.92.x -- that declare Requires-Python <3.14. uv ignores that upper bound and installed 1.85.7 anyway, but pip does not: on Python 3.14, `pip install memmachine-server[litellm]` resolves to 1.83.7, not the 1.85.7 in the lock. 1.93.0 is the first release that supports 3.14, so that is the floor now, and the lock moves to 1.101.0. litellm also requires openai<3, which is what holds the OpenAI SDK on the 2.x line; without the floor the resolver satisfies that by walking litellm backwards to 1.83.0 instead. - boto3-stubs was pinned exactly at 1.43.13 while boto3 resolved to 1.43.47, so the stubs no longer described the installed SDK. One source change the new versions require, and one cleanup: - `list(vector.flat)` is a list of numpy scalars, not `list[float]`, which the newer numpy typing now reports at the assignment. The replay path converts explicitly. - The dev group listed complexipy twice. Left behind deliberately: nebula5-python (see the cap and its reason), openai 3.x (litellm requires openai<3, and instructor's jiter<0.15 pin holds openai below 3.11 regardless; 3.0 also swaps the transport to httpx2), and ruff, still pinned at 0.15.14 -- 0.16 formats Markdown code blocks, which would reformat six docs, and adds LOG004, which flags four `logger.exception` calls, two of them genuine misuses and two in a helper that is only ever called from an except block. Same change as the first half of MemMachine#1596 on speedkick, applied to main. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Four entries in the server's dependency list are not requirements of this package: - boto3-stubs is a type-stub distribution sitting in the runtime list. Nothing imports it, and `ty check --project packages/server` reports the same "All checks passed" with the package uninstalled, so it was buying neither runtime behavior nor type coverage. (Base boto3-stubs only types the boto3 entry points; per-service clients need the mypy-boto3-* extras. If stronger boto3 typing is wanted later, that belongs in the dev group with those extras.) - regex belongs to memmachine-common, which declares it and imports it in api/spec.py. Nothing in the server package uses it. - The PyPI "dotenv" distribution ships no modules at all -- only dist-info -- and exists to depend on python-dotenv. `importlib.metadata.packages_distributions()["dotenv"]` is `["python-dotenv"]`, so `from dotenv import load_dotenv` has always been python-dotenv. Declare that instead. - greenlet is what SQLAlchemy's asyncio extra installs, and this package uses create_async_engine, so ask for `sqlalchemy[asyncio]` and let it bring greenlet. That also covers the platforms SQLAlchemy's own platform_machine marker on greenlet leaves out. The lock loses boto3-stubs, botocore-stubs, types-s3transfer and dotenv. reranker_manager also took runtime_checkable from typing_extensions, an undeclared dependency it reached through pydantic. It has been in typing since 3.8 and this package requires 3.12, so it now comes from typing, next to the Protocol the file already imports there. memmachine-common and memmachine-client keep their typing_extensions dependency: they support 3.10, and Self and Unpack are 3.11. Same change as the second half of MemMachine#1596 on speedkick, applied to main. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
3499ca8 to
5795c58
Compare
openai_embedder's dimensionality check and amazon_bedrock_reranker's score-count check each call logger.exception() and then raise their own ExternalServiceAPIError. Nothing is being handled at that point: logger.exception is error(..., exc_info=True), and with no active exception it appends "NoneType: None" to the record. logger.error is what both sites mean; the raise that follows carries the message. ruff 0.16 reports both as LOG004 (`.exception()` call outside exception handlers). Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
_handle_get_project_http_error takes the caught HTTPError as a parameter, but its bare `raise` statements and logger.exception() calls ignored it and used the exception the *caller's* except block had active. That works only while the helper is called from inside that block, and ruff 0.16's LOG004 cannot see the call boundary, so it reports the two logging calls as .exception() outside a handler. The helper now uses what it is handed: logger.error(..., exc_info=error) attaches the same traceback logger.exception would have, and `raise error` re-raises the same object. Callers observe no difference: the exception identity, its original traceback and the 422 ValueError's __cause__ are unchanged (the helper's own frame is appended to the traceback, as it is for any re-raise from a callee). Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
ruff was held at 0.15.14 by the dependency refresh because 0.16 brings two things that touch committed content, and both now have their own commits ahead of this one: - LOG004 (`.exception()` outside an exception handler), selected via the LOG group. Its four findings are resolved by the two preceding commits, so `ruff check` is clean at this pin with no suppressions. - The formatter now formats Python code blocks inside Markdown. The six docs it touches are reformatted here, by `ruff format` and nothing else: USAGE.md, examples/v1/README.md, integrations/aws_strands_agent_sdk/README.md, integrations/langgraph/README.md, maintainers/build-pip-packages.md, packages/client/README.md. Trailing commas, collapsed argument lists, and column-aligned comments brought to two spaces; no words change. The lint workflow's ruff-action reads the pin from pyproject.toml, so CI enforces 0.16.8 from this commit on. No .py file is reformatted by the new version. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
marvinyu-memverge
left a comment
There was a problem hiding this comment.
Read this at 0f3cd48 - the lock changes, the drops, the four source hunks and the CI wiring all check out. One ask.
1. Cap openai<3 in the server's own dependency list. The openai<3 this PR leans on lives in the optional litellm extra, so a plain pip install memmachine-server never sees it, and instructor allows openai<4. The PR's own installation-test job shows what pip does with that: it installed openai 3.3.0 (with httpx2 2.13.0) while the lock says 2.54.0. 3.3.0 is the last 3.x that accepts instructor's jiter<0.15 (3.3.1 onward need jiter>=0.16), so pip walks back from 3.14.1 to there rather than to 2.x. It is the same lock-vs-pip split this PR fixes for litellm, in the other direction - pre-existing since openai 3.0.0 landed in August, but this is the PR that reasons about the mechanism. Since 3.x is its own PR per the description, openai>=2.21.0,<3 on the server package states that; the lock does not move.
Verified: ruff-action reads the pin from pyproject.toml via version-file; the lock drops boto3-stubs/botocore-stubs/types-s3transfer/dotenv and keeps greenlet + python-dotenv through sqlalchemy[asyncio] and the direct dependency; regex and typing_extensions have no imports left in the server package, dotenv has three; on PyPI, dotenv 0.9.9 requires only python-dotenv, litellm 1.85.7 is <3.14 and 1.93.0 is the first <3.15, litellm 1.101.0 requires openai<3.0.0, instructor 1.17.0 requires jiter<0.15 and openai<4; fastmcp.server.http.StarletteWithLifespan still resolves under fastmcp 4.0.3 with the MCP test suite green; raise error in the client helper is the active exception, so the object, traceback and 422 __cause__ are unchanged.
The litellm extra's comment also said litellm's openai<3 is what keeps the resolved OpenAI SDK on the 2.x line. That describes the universal lock, which resolves every extra, and not a requirement of this package: the server hands the SDK no httpx client, which is the only thing openai 3.0 changed, and its suite passes on openai 3.3.0 with the extra absent (1869 passed, 3 skipped, the same as on the lock). Installs without the extra may resolve openai 3.x. The comment now states only the floor, which is this package's own decision. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
|
Written by Claude: Not capping, though. The runtime list declares what this package's code needs: floors from the APIs it uses, caps only where its own code is incompatible. The What makes that safe: 3.0's one breaking change is the HTTP layer (httpx to httpx2), and it only affects code that hands the SDK a custom httpx client or transport. The server passes none ( Changed at 83e3a95: the litellm extra's comment no longer says litellm's cap is what keeps openai on 2.x (it now explains only the floor), and the description's "openai 3.x" bullet says the above instead of "worth its own PR". Lock untouched, The gap that remains — the uv matrix only ever exercises the lock, so declared ranges get validated only when someone runs what I ran — is real, and the non-hacky fix is a CI job that installs from metadata and runs the suite instead of import checks. Separate issue, not this PR. |
Rebased onto
mainafter #1645 merged (its relock commit is what makes this PR'suv lock --checkmeaningful at all). Five commits: refresh the lock, drop dependencies that are not requirements of these packages, then the three that move ruff to 0.16. This is #1596 applied tomain, relocked against today's index rather than cherry-picked, since the two branches' locks had diverged.Supersedes dependabot's #1583 and #1614, which bump
boto3-stubs's exact pin and widenlitellm's cap: after this PRboto3-stubsis gone andlitellmhas a floor instead of a cap.1. Bring the lock up to date
30 of the 52 direct dependencies were behind their latest release. The refresh moves 112 locked packages, adds 6, removes 2, and downgrades none.
Nine major bumps: complexipy 6→8, cryptography 49→50, fastmcp 3→4 (and fastmcp-slim), mcp 1→2, sentence-transformers 5→6, setuptools 83→84, websockets 16→17, xxhash 3→4. Direct dependencies moving include fastapi 0.139.0→0.141.1, instructor 1.15.4→1.17.0, langchain-aws 1.6.2→1.7.6, litellm 1.85.7→1.101.0, neo4j 6.2.0→6.3.1, openai 2.45.0→2.54.0, qdrant-client 1.18.0→1.19.0, sqlalchemy 2.0.51→2.0.53, ty 0.0.59→0.0.81, uvicorn 0.51.0→0.53.0.
litellm's upper bound had to go. It was introduced as
<1.85by the PR that added the provider (#1386, whose description states the dependency that way but records no reason for the bound); dependabot later widened it to<1.86. Either way the range ends inside a run of releases — 1.83.8 through 1.92.x — that declareRequires-Python <3.14(<3.14,>=3.9from 1.83.8,<3.14,>=3.10from 1.83.10). uv ignores that upper bound and installed 1.85.7 anyway; pip does not:So a pip user on 3.14 got 1.83.7 while the lockfile said 1.85.7. 1.93.0 is the first release supporting 3.14 (
<3.15,>=3.10), so that is the floor now, and the lock moves to 1.101.0.The floor also does work a cap would do badly. litellm requires
openai<3, which is what holds the OpenAI SDK on the 2.x line in the lock — and left uncapped, the resolver satisfiesopenai<3by walking litellm backwards to 1.83.0 (whoseopenai>=2.8.0has no upper bound) rather than holding openai back. Stating the litellm requirement keeps the constraint where it belongs, and it lifts itself the day litellm supports openai 3.One source change the new versions require: newer numpy typing catches
list(vector.flat)not beinglist[float](the SQLite vector store's replay path converts explicitly). The dev group also listedcomplexipytwice.2. Drop dependencies nothing declares them for
ty check --project packages/serverreports the sameAll checks passedwith it uninstalled, so it bought neither runtime behavior nor type coverage. (Base boto3-stubs only types the boto3 entry points; per-service clients need themypy-boto3-*extras. If stronger boto3 typing is wanted, that belongs in the dev group with those extras.) It was also pinned exactly at 1.43.13 while boto3 ran to 1.43.47 — boto3-stubs mirrors boto3 release for release, so an exact pin goes stale within days, which is why dependabot keeps opening PRs for it.api/spec.py. Nothing in the server package uses it.dotenvdistribution ships no modules at all, only dist-info, and exists to depend on python-dotenv.importlib.metadata.packages_distributions()["dotenv"]is["python-dotenv"], sofrom dotenv import load_dotenvhas always been python-dotenv.sqlalchemy[asyncio]— greenlet is exactly what SQLAlchemy's asyncio extra installs, and this package usescreate_async_engine. Asking SQLAlchemy for it also covers the platforms SQLAlchemy's ownplatform_machinemarker on greenlet leaves out.The lock loses boto3-stubs, botocore-stubs, types-s3transfer and dotenv. greenlet and python-dotenv stay, now for stated reasons.
reranker_manageralso tookruntime_checkablefrom typing_extensions, an undeclared dependency it reached through pydantic. It has been intypingsince 3.8 and this package requires 3.12, so it now comes fromtyping, next to theProtocolthe file already imports there. memmachine-common and memmachine-client keep their typing_extensions dependency — they support 3.10, andSelfandUnpackare 3.11.Kept deliberately, though nothing imports them, because each is named in the source or by the tests:
DatabaseBackendspells them out —POSTGRES = ("postgres", SqlAlchemyConf, "postgresql", "asyncpg")— andSqlAlchemyConfrenders{dialect}+{driver}://forcreate_async_engine.prompt_utilitiesbuildszoneinfo.ZoneInfo(tz), and Windows ships no system tz database, so without it every lookup — including the UTC fallback in theexceptbranch — raisesZoneInfoNotFoundError.pathdeployment mode and fortest_milvus_vector_store, which opensMilvusClient(uri=tmp_path / "test_milvus.db")behindpytest.importorskip("milvus_lite").3–5. Move ruff to 0.16.8
Originally left behind; folded in on request. 0.16 brings two things that touch committed content, each isolated in its own commit so the diff reads as what it is:
.exception()called outside an exception handler) fires four times onmain. Two are genuine misuses:openai_embedderandamazon_bedrock_rerankercalllogger.exception(msg)and thenraise ExternalServiceAPIError(msg)with nothing in flight, so the record getsNoneType: Noneappended. They becomelogger.error(commit 3). The other two are in the client's_handle_get_project_http_error, which is only ever called from inside anexceptblock, so they were correct — but the helper ignored theerrorit is handed and leaned on the caller's active exception for its bareraiseandlogger.exceptiontoo. It now uses its parameter:logger.error(..., exc_info=error)andraise error(commit 4). Callers see the same exception object, the original traceback and the same 422ValueError.__cause__; verified directly, and the client suite passes. No suppressions.ruff formatalone (commit 5):USAGE.md,examples/v1/README.md,integrations/aws_strands_agent_sdk/README.md,integrations/langgraph/README.md,maintainers/build-pip-packages.md,packages/client/README.md. Trailing commas, collapsed argument lists, column-aligned comments brought to two spaces; no words change. No.pyfile is reformatted.The lint workflow's
ruff-actionreads the pin frompyproject.toml, so CI enforces 0.16.8 from commit 5 on. Each of the three commits is clean under its own pin (ruff checkandruff format --checkat 0.15.14 for commits 3–4, at 0.16.8 for commit 5).Deliberately left behind
<5.3in Fix the ty static checks #1645; 5.3 has no public async client.litellmextra too, and every litellm release through 1.103.0.dev1 capsopenai<3. That is a property of the lock, not a requirement of this package, so the server declares no cap. 3.0's one breaking change is the HTTP layer (httpx to httpx2), which affects only code that hands the SDK a custom httpx client or transport; the server passes none. Verified: the server suite with every extra except litellm and openai forced to 3.3.0 — the version pip resolves formemmachine-servertoday, held there by instructor'sjiter<0.15(3.3.1 onward needjiter>=0.16) — is 1869 passed, 3 skipped, the same as on the lock. Installs without the litellm extra may resolve 3.x; that is intended.packages/ts-client,integrations/openclaw) — a separate ecosystem with its own dependabot PRs; untouched here.Verification
Locked and checked with uv 0.12.15, the version
setup-uvinstalls in CI. All sixtyjobs,ruff check,ruff format --checkanduv lock --checkpass after each commit. Unit suite after commit 2: server 1869 passed, 3 skipped; client 255 passed; commits 3–5 change two log levels, one helper and six docs, and the client suite plus the touched server tests pass at the tip.Related: #1596 (same change on
speedkick, merged).🤖 Generated with Claude Code