Skip to content

Fix the ty static checks (speedkick) - #1595

Merged
edwinyyyu merged 1 commit into
MemMachine:speedkickfrom
edwinyyyu:fix/ty-diagnostics-speedkick
Sep 9, 2026
Merged

edwinyyyu merged 1 commit into
MemMachine:speedkickfrom
edwinyyyu:fix/ty-diagnostics-speedkick

Conversation

@edwinyyyu

Copy link
Copy Markdown
Contributor

The lint workflow's six ty jobs (common, client and server, each on the oldest and newest supported Python) fail on every pull request. This makes all six pass.

The NebulaGraph half

Nine of the eighteen diagnostics are a real breakage rather than a typing nit. nebula5-python 5.3.0 removed NebulaAsyncClient, SessionConfig and SessionPoolConfig — all three in nebulagraph_python.client.__all__ in 5.2 — so nebula5-python>=5.2.1 resolves to a release whose import the NebulaGraph backend cannot even complete: async_get_nebula_client raises ImportError at its use site, and nebula_graph_vector_graph_store has no client type to annotate.

Porting forward is not available yet. 5.3's AsyncNebulaClient has no public way to open a connection:

  • NebulaAsyncClient.connect(hosts=..., username=..., session_config=..., session_pool_config=...) is gone.
  • AsyncNebulaClient.__init__ leaves connection = None and session_id = -1, and its public surface is close, execute, execute_with_timeout, execute_py, ping, pq, print_query_result, is_closed_client and the get_* accessors — no connect, open or __aenter__.
  • The only initializer left is the private _init_client(), which nothing in the package calls.

Its sync NebulaClient, NebulaPool and ClientPoolFactory are complete, so the ways forward are private API or running blocking gRPC calls off the event loop — a backend rewrite, not a lint fix. This PR caps the extra at <5.3, the range the backend actually supports, and documents why at the declaration. Relocking also drops the runtime dependencies on pytest and pool that 5.3.0 added.

The rest

  • The four missing-argument diagnostics were tests that deliberately omit a required field. They now go through model_validate() with a dict, so pydantic — not a suppression comment — is what rejects the input.
  • test_delete_episode_store_processes_in_batches assigned a mock over a bound method behind a # type: ignore / # ty: ignore pair; it now uses monkeypatch.setattr, and both comments are gone.
  • test_password_mixin_invalid_type loses its blanket # type: ignore the same way.
  • cast(ResponseFunctionToolCall, output) was redundant — ty narrows output on the output.type != "function_call" guard. It is now an annotation, so the narrowing is proved rather than asserted.
  • _format_search_summary sliced values pulled out of a model_dump()ed dict, which are not necessarily str; a non-str value would have raised TypeError at runtime. They are stringified before slicing.

No # type: ignore, # ty: ignore, Any or cast was added.

Verification

ty check passes for packages/common (3.10, 3.14), packages/client (3.10, 3.14) and packages/server (3.12, 3.14) — the six CI jobs. ruff check, ruff format --check, uv lock --check and the unit suite pass. The touched tests were run directly, including the integration-marked batch-deletion one.

Out of scope: the repository-root ty check, which CI does not run, still reports diagnostics under evaluation/, examples/, integrations/ and tools/.

🤖 Generated with Claude Code

https://claude.ai/code/session_01BcPSoGsQjnVJS8A5NkoGZN

The lint workflow's ty jobs (common, client and server, each on the
oldest and newest supported Python) fail on every pull request. Nine of
the eighteen diagnostics are a real breakage rather than a typing nit:
nebula5-python 5.3.0 removed NebulaAsyncClient, SessionConfig and
SessionPoolConfig -- all of them in nebulagraph_python.client's __all__
in 5.2 -- so the `>=5.2.1` specifier resolved to a release the
NebulaGraph backend cannot import at all.

5.3's replacement, AsyncNebulaClient, has no public way to open a
connection: NebulaAsyncClient.connect() is gone, __init__ leaves
connection None and session_id -1, and the only initializer left is the
private _init_client(), which nothing in the package calls. Its sync
NebulaClient and NebulaPool are complete, so moving forward means
either private API or running blocking gRPC in the async server. Cap the
extra at <5.3 for now, which is the range the backend actually supports.
Relocking also drops the runtime dependencies on pytest and pool that
5.3.0 added.

The rest:

- Construct the deliberately-invalid language-model parameters and API
  key through model_validate(), so pydantic rejects them and no static
  check has to be suppressed to express the test.
- Set the mocked _cleanup_semantic_history with monkeypatch.setattr
  instead of assigning over the bound method.
- Annotate the narrowed function-call output rather than casting it: ty
  now proves what the cast used to assert.
- Stringify the LangGraph search-summary content before slicing it. It
  comes out of a model_dump()ed dict, so it is not necessarily a str,
  and a non-str value would have raised TypeError at runtime.

`ty check` passes for all three projects across the versions CI checks,
as do `ruff check`, `ruff format --check`, `uv lock --check` and the
unit suite. The repository-root `ty check`, which CI does not run, still
reports diagnostics under evaluation/, examples/, integrations/ and
tools/.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01BcPSoGsQjnVJS8A5NkoGZN
@edwinyyyu
edwinyyyu merged commit 1bfbc13 into MemMachine:speedkick Sep 9, 2026
31 of 40 checks passed
malatewang pushed a commit that referenced this pull request Sep 16, 2026
* Relock: the server never declared datasets

uv.lock records datasets>=5.0.0 as a requirement of memmachine-server,
and locks datasets, dill and multiprocess for it, but no pyproject in
the workspace declares datasets. The entry arrived with #1477's lock
(2026-08-13), whose pyproject changes added only the spaCy group, so
`uv lock --check` has failed on main since then. Nothing caught it
because the lock-check workflow runs only for pull requests that touch
a dependency file, and the only such pull requests since have been
dependabot's, for which the workflow regenerates the lock instead of
checking it.

Relocking removes the phantom requirement and the three packages that
existed only to satisfy it (datasets, dill, multiprocess), plus the
fsspec[http] extra that only datasets pulled in. No version moves.
The evaluation scripts that import datasets do so lazily and were
never covered by the lock.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>

* Fix the ty static checks

The lint workflow's ty jobs (common, client and server, each on the
oldest and newest supported Python) fail on every pull request. Nine of
the eighteen diagnostics are a real breakage rather than a typing nit:
nebula5-python 5.3.0 removed NebulaAsyncClient, SessionConfig and
SessionPoolConfig -- all of them in nebulagraph_python.client's __all__
in 5.2 -- so the `>=5.2.1` specifier resolved to a release the
NebulaGraph backend cannot import at all.

5.3's replacement, AsyncNebulaClient, has no public way to open a
connection: NebulaAsyncClient.connect() is gone, __init__ leaves
connection None and session_id -1, and the only initializer left is the
private _init_client(), which nothing in the package calls. Its sync
NebulaClient and NebulaPool are complete, so moving forward means
either private API or running blocking gRPC in the async server. Cap the
extra at <5.3 for now, which is the range the backend actually supports.
Relocking also drops the runtime dependencies on pytest and pool that
5.3.0 added.

The rest:

- Construct the deliberately-invalid language-model parameters and API
  key through model_validate(), so pydantic rejects them and no static
  check has to be suppressed to express the test.
- Set the mocked _cleanup_semantic_history with monkeypatch.setattr
  instead of assigning over the bound method.
- Annotate the narrowed function-call output rather than casting it: ty
  now proves what the cast used to assert.
- Stringify the LangGraph search-summary content before slicing it. It
  comes out of a model_dump()ed dict, so it is not necessarily a str,
  and a non-str value would have raised TypeError at runtime.

Same change as #1595 on speedkick, applied to main.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>

---------

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant