Skip to content

Add test suite, fix three import-time bugs, target Python 3.12/3.13#7

Merged
Magic-Man-us merged 1 commit into
mainfrom
claude/tests-py313
Jul 20, 2026
Merged

Add test suite, fix three import-time bugs, target Python 3.12/3.13#7
Magic-Man-us merged 1 commit into
mainfrom
claude/tests-py313

Conversation

@Magic-Man-us

Copy link
Copy Markdown
Owner

Summary

Adds a 46-test suite (passing on CPython 3.12 and 3.13), which immediately surfaced and fixed three real import-time bugs — two of which made whole subsystems unusable. No CI workflow is included, per preference; run locally with uv sync --extra dev && uv run pytest (the sync builds the Rust extension via maturin).

Bugs found by the tests (fixed here)

  1. Missing dependency: pydantic-settings — imported by config.py and storage/settings.py but never declared, so any clean install crashed with ModuleNotFoundError on import memory_core_py. Added to dependencies.
  2. storage/database.py: datetime imported under TYPE_CHECKING only — SQLAlchemy resolves Mapped[datetime] annotations at class-declaration time, so importing the package raised MappedAnnotationError. Moved to a runtime import with a comment explaining why it must stay.
  3. core/models.py: SMK enums (TopicBucket, MemoryKind, ToolFlag) imported under TYPE_CHECKING only — they're Pydantic field types on AssistantMemoryTrace, leaving the model permanently "not fully defined" (PydanticUserError) and breaking the entire assistant-memory/SMK feature on first construction.

Test coverage

  • SMK layer — quantization bucket boundaries (_quantize_level at 0.25/0.5/0.75 edges), build_smk_features tool-mask OR-composition and scalar→bucket mapping.
  • ModelsMemoryTrace.to_rust_args() exact positional order and types (guards the Rust FFI contract the code comments call out), unit-interval bounds on AssistantMemoryTrace, frozen MemoryCandidate.
  • Settings — MySQL DSN construction (mysqlconnector driver), Redis DSN with password/url-override precedence, apply_overrides sanitization (unknown keys and None values dropped; no-op returns the same instance).
  • MemorySystem orchestration (protocol fakes, no MariaDB/Redis needed) — remember fan-out: STM insert with created_at + ttl expiry, LTM upsert, index ingest, working-memory event, also_working_mem=False, optional STM; recall aggregation of LTM/WM/STM layers with the include toggle; assistant paths no-op without an index.
  • RedisWorkingMemory — against an in-memory fake client: timestamp stamping, TTL application, lrange(-limit, -1) recency semantics, per-user partitioning.
  • Real Rust engine (pytest.importorskip("memory_core"), so it auto-skips where the extension isn't built) — RustMemoryIndex ingest/search ranking, per-user isolation, remove/mark_accessed; AssistantMemoryIndex id→trace_uid mapping, topic filtering, and required-tools mask filtering through PySmkQuery.

Packaging

  • requires-python stays >=3.12; .python-version pins the preferred 3.13; 3.12/3.13 trove classifiers added.
  • pytest-asyncio added to the dev extra; [tool.pytest.ini_options] configures testpaths, pythonpath=["."], and asyncio auto mode.
  • uv.lock regenerated for the dependency fix.

Verified by building the extension and running the full suite on both interpreters: 46 passed on 3.12.3 and on 3.13.12.

🤖 Generated with Claude Code

https://claude.ai/code/session_016erjEoxcmpDXDVGqaqf7Xt


Generated by Claude Code

Tests (46, passing on CPython 3.12 and 3.13):
- SMK quantization boundaries and feature extraction (tool-mask OR,
  bucket mapping)
- Model invariants: to_rust_args positional order (guards the Rust FFI
  contract), unit-interval bounds, frozen candidates
- Storage settings: DSN construction, override sanitization
- MemorySystem orchestration with protocol fakes: remember fan-out
  (STM TTL expiry, LTM upsert, index ingest, WM event), recall
  aggregation, optional STM/assistant paths
- RedisWorkingMemory against an in-memory fake client (timestamping,
  TTL, limit semantics, per-user partitioning)
- Real Rust engine round trips (built via maturin): vector search
  ranking, per-user isolation, remove/mark_accessed, SMK assistant
  index topic/tool filtering and id->uid mapping; auto-skips when the
  extension is absent

Bug fixes the tests surfaced:
- pydantic-settings was imported (config.py, storage/settings.py) but
  never declared as a dependency: clean installs crashed on import
- storage/database.py imported datetime under TYPE_CHECKING while
  SQLAlchemy needs it at runtime to resolve Mapped[datetime]:
  importing the package raised MappedAnnotationError
- core/models.py imported the SMK enums under TYPE_CHECKING while
  they are pydantic field types: AssistantMemoryTrace was permanently
  "not fully defined", breaking the entire assistant-memory feature

Packaging: pytest-asyncio in dev extras, pytest config (testpaths,
pythonpath, asyncio auto), 3.12/3.13 classifiers, .python-version
pinned to the preferred 3.13.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016erjEoxcmpDXDVGqaqf7Xt
Copilot AI review requested due to automatic review settings July 20, 2026 02:41

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds a comprehensive Python test suite for memory_core_py and uses it to identify/fix three import-time failures that prevented clean installs and key subsystems from working, while explicitly targeting Python 3.12/3.13 for development and packaging.

Changes:

  • Added a new pytest suite (46 tests) covering SMK feature extraction, settings DSN/override behavior, MemorySystem orchestration, Redis working memory behavior, and optional Rust-extension round trips.
  • Fixed import-time issues by making required types available at runtime (SQLAlchemy Mapped[datetime] and Pydantic enum field types).
  • Updated packaging/dev dependencies and pytest configuration (adds pydantic-settings and pytest-asyncio, pins preferred Python via .python-version).

Reviewed changes

Copilot reviewed 11 out of 12 changed files in this pull request and generated no comments.

Show a summary per file
File Description
uv.lock Locks in pydantic-settings and pytest-asyncio to support runtime settings imports and async tests.
pyproject.toml Declares new dependencies/extras, adds 3.12/3.13 classifiers, and configures pytest + asyncio mode.
.python-version Pins preferred local interpreter to Python 3.13.
memory_core_py/storage/database.py Fixes SQLAlchemy annotation resolution by importing datetime at runtime.
memory_core_py/core/models.py Fixes Pydantic model completeness by importing SMK enums at runtime.
tests/conftest.py Adds shared fakes/fixtures for storage/index/working-memory tests without external services.
tests/test_models.py Adds invariants/contract tests for Pydantic models and Rust-FFI argument ordering.
tests/test_settings.py Adds DSN construction and override-sanitization tests for storage settings.
tests/test_smk.py Adds SMK quantization and feature-extraction tests, including tool-mask behavior.
tests/test_system.py Adds orchestration tests for MemorySystem remember/recall and assistant paths.
tests/test_working_memory.py Adds async tests validating Redis working-memory semantics using an in-memory fake client.
tests/test_rust_engine.py Adds integration tests that exercise the real Rust bindings when available (auto-skipped otherwise).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@Magic-Man-us
Magic-Man-us merged commit 50af86c into main Jul 20, 2026
1 check passed
Magic-Man-us pushed a commit that referenced this pull request Jul 20, 2026
Main's PR #7 independently fixed the same three import-time bugs (runtime
datetime in storage/database.py, runtime SMK enums in core/models.py,
undeclared pydantic-settings) in the old memory_core_py layout and added a
46-test suite for the Redis/MariaDB architecture. This branch had already
replaced that architecture, so the merge keeps the SQL-only layout and
ports everything portable from main:

- adopted: 3.12/3.13 classifiers, .python-version (3.13), pytest-asyncio
  fixture-loop-scope config, the explanatory noqa: TC001 comment on the
  runtime enum imports, pydantic-settings>=2.6 floor
- ported to the new layout: SMK quantization/feature tests, Rust-engine
  wrapper round trips (ranking, isolation, remove/mark_accessed, id->uid
  mapping, topic/tool filters), model invariants (frozen candidates,
  unit-interval bounds, to_rust_args order), remember/recall skip flags,
  make_trace/make_assistant_trace factories
- dropped with the old architecture: Redis working-memory tests and fake
  client, MySQL DSN settings tests, protocol-fake orchestration tests now
  covered end-to-end against real SQLite + the real index

59 tests pass; ruff clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018W7Afhk8WCxZcHtwj3dYHH
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.

3 participants