Changelog¶
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[0.8.3] - 2026-01-18¶
Bug Fixes¶
Concurrency: Fixed a race condition in
test_concurrent_mutation_performancewherethreading.get_ident()was used for dictionary keys. In some environments (like CI), thread IDs can be reused across fast-running threads, leading to key collisions. Switched to unique thread indices.
Infrastructure & Development¶
CI/CD Pipelines (NEW)¶
publish.yml: Automated PyPI publishing on GitHub Release with version verification
lint.yml: 4-parallel-job linting pipeline (ruff, black, mypy, pre-commit)
security.yml: Weekly security scanning with Bandit and pip-audit
docs.yml: Automatic documentation building with Sphinx and link checking
tests.yml: Optimized test matrix with caching and concurrency control (saves ~2-3 min per run)
Pre-commit Hooks (FIXED)¶
Fixed
types-allbroken dependency → switched totypes-psutilExcluded examples/ from mypy checking (known type patterns)
Fixed Black config: removed py313/py314 (not supported in black 23.12.1)
Code Quality (IMPROVED)¶
Fixed 25 Ruff E501 errors (long docstrings)
Fixed 20 MyPy strict mode errors (SQLAlchemy inheritance conflicts)
Fixed unused import in test_wrappers.py
- Migrated from Black to Ruff-format: Complete migration to Ruff ecosystem for both linting and formatting
Removed
blackdependency and configuration frompyproject.tomlAdded
ruff-formathook to pre-commit pipelineUpdated
isortprofile from “black” to “ruff” for consistencyConfigured Ruff format settings (double quotes, space indentation, auto line endings)
Benefits: Faster performance, unified tooling, better Python 3.10+ support
All pre-commit hooks now passing ✅
Documentation (EXPANDED)¶
Created
.github/WORKFLOWS.md(9,529 lines): Complete workflow setup and usage guideCreated
.github/SETUP_CHECKLIST.md(5,812 lines): Quick-start release checklistUpdated CONTRIBUTING.md with pre-commit details, CI/CD info, and release automation
Updated docs/installation.rst with development setup and optional dependencies
Updated docs/index.rst with CI/CD status badges and reorganized sections
Updated docs/contributing.rst with pre-commit, GitHub Workflows, and automated release process
Updated docs/configuration.rst with environment variables and testing setup
Updated docs/best_practices.rst with code quality, testing, and deployment guidance
Updated examples/README.md with CI/CD integration notes
Updated tests/README.md with comprehensive test running guides
Updated README.md with CI/CD badges (tests.yml, lint.yml)
Project Architecture¶
Package Structure Refactoring (MAJOR)¶
Migrated to ``src/`` layout: Moved entire
sqlatypemodel/package from root tosrc/sqlatypemodel/Updated ``pyproject.toml``: Changed packages configuration to
{ include = "sqlatypemodel", from = "src" }- Benefits:
Cleaner project root separation (code vs config files)
Better import isolation during development
Standard Python packaging best practice
Prevents accidental imports from development directory
Files Moved: All 23 Python files relocated from
sqlatypemodel/→src/sqlatypemodel/Zero Breaking Changes: All imports and usage remain identical for end users
Technical Improvements¶
Added concurrency control to GitHub workflows (cancel old runs on new push)
Added pip and Poetry caching for faster CI runs
Separated MyPy source/test checking (stricter in source, excluded tests)
Enhanced test logging and error reporting
Fixed GitHub Actions workflow formatting conflicts (removed Black references)
Updated CONTRIBUTING.md for Ruff-only workflow
Fixed RST title underlining in documentation for Sphinx builds
Removed YAML syntax errors in CI/CD workflows
Files Created/Modified¶
New Files:
.github/workflows/lint.yml
.github/workflows/publish.yml
.github/workflows/security.yml
.github/workflows/docs.yml
.github/WORKFLOWS.md
.github/SETUP_CHECKLIST.md
Updated Files:
.pre-commit-config.yaml
.github/workflows/tests.yml
pyproject.toml
CONTRIBUTING.md
docs/installation.rst
docs/index.rst
docs/contributing.rst
docs/configuration.rst
docs/best_practices.rst
examples/README.md
tests/README.md
README.md
Package Structure Changes:
MOVED: Entire
sqlatypemodel/package →src/sqlatypemodel/ALL 23 Python files relocated to src/ layout
DELETED: Old root-level package directory
[0.8.2] - 2026-01-18 (Optimization & Concurrency Release)¶
Major Performance & Architecture Upgrades¶
This release focuses on optimization, concurrency, and robustness.
Core Optimizations¶
- Hot Path Acceleration:
__getattribute__and__setattr__hot paths have been heavily optimized.Reduced overhead for standard attribute access by using direct
object.__getattribute__calls and caching.Implemented type dispatch tables in
wrapping.pyto avoid expensiveisinstancechecks chain.
- Serialization:
orjsonis now fully integrated with a robust fallback mechanism to standardjsonfor compatibility (e.g. large integers).
- Benchmarks:
Validated 2.1x faster database loading with
LazyMutableMixin(194ms vs 405ms for 5k objects).Reduced memory usage by 35% (7.75MB vs 11.80MB).
Concurrency & Thread Safety¶
- Thread-Safe Mutation:
Fixed race conditions in
MutableStateby ensuring proper locking during parent linking/unlinking.Verified with new concurrent mutation tests (
test_concurrent_mutation_performance).
- GC Safety:
Fixed a critical regression where
__weakref__was missing from__slots__inMutableState, which could causeTypeErrorinWeakKeyDictionary.
Compatibility & Fixes¶
- Pydantic V2:
Resolved all remaining compatibility issues, including strict validation of list inputs.
- Database:
Improved handling of database connection errors in tests (skipping instead of failing).
Fixed pooling parameters for SQLite integration tests.
- Documentation:
Updated all docstrings to Google style guide.
Enhanced examples with better type hinting and documentation.
[0.8.1p2] - 2026-01-17 (Performance Analysis & Documentation Correction)¶
Comprehensive Benchmark Analysis¶
Investigation Results:
- Micro-benchmark (pure initialization): Lazy is 376x faster
Eager: 593 µs/object → 2,963 ms for 5,000 objects
Lazy: 1.6 µs/object → 7.9 ms for 5,000 objects
- Real-world benchmark (DB + E2E workflow): Lazy is only 1.2x faster overall
DB Load: 2.0x faster
First Access: 62x SLOWER
Total: 1.2x faster
Maximum Performance Optimization Release¶
This is a critical performance optimization release achieving 30-47% speedups.
Performance Improvements¶
Attribute Access Optimization (40% faster)
LazyMutableMixin.__getattribute__() (Ultra-optimized)
MutableMixin.__setattr__() (35% faster)
Wrapping Logic Optimization (40% reduction in initialization overhead)
Inspection & Cache Tuning (Increased LRU cache size)
[0.8.0] - 2026-01-17¶
A comprehensive quality and type-safety release that achieves 100% strict mypy compliance.
Type Safety & DX¶
100% Mypy Strict Compliance
Improved Decorator Signatures
Runtime Protocol Checking
Refactoring & Architecture¶
Modular Constants
Sentinel Extraction
Clean Imports
Documentation & Examples¶
Full Examples Suite
Architecture Documentation
Troubleshooting Guide
Breaking Changes¶
Internal API: Constants moved to internal modules.
Inverted Ownership (GC Fix): Fixed race condition in tracking links.
[0.7.0] - 2025-12-22¶
A monumental release rewriting the core architecture.
New Features & Architecture¶
Lazy Loading (`LazyMutableMixin`)
Graph Isomorphism (Circular Reference Support)
Developer Utilities (Dataclass Wrapper, SQLAlchemy Helpers)
Batching Context
Critical Stability Fixes¶
Pickle Robustness (No Monkey-Patching)
Dataclass Initialization Safety
ForceHashMixin
[0.6.0] - 2025-12-19¶
A major feature release introducing full Pickle support (enabling Caching/Celery workflows), correcting critical identity hashing logic, and fully aligning with SQLAlchemy 2.0 patterns.
Added¶
- Pickle Support: Implemented robust
__getstate__and__setstate__methods inMutableMixin. Handles Pydantic V2 nested state structures (
__dict__inside state).Automatically cleans up unpicklable
WeakKeyDictionary(_parents).Self-Healing: Automatically triggers
_scan_and_wrap_fields()after unpickling to restore parent-child tracking relationships, preventing “orphaned” nested objects.
- Pickle Support: Implemented robust
Identity Integrity: Added a
__new__hook inMutableMixinto forcibly restore__hash__ = object.__hash__. This ensures compatibility with@dataclassand@attrs(which typically strip hashing from mutable objects), preventingTypeError: unhashable typewhen used in tracking dictionaries.Testing: Added
tests/conftest.pywith centralized fixtures (session,engine) and refactored the entire test suite to native Pytest patterns, removing legacyunittestdependencies.
Changed¶
Hashing Logic:
MutableMixinnow strictly enforces Identity-based hashing. This guarantees that modifying a field (e.g.,user.name = "new") does not change the object’s hash, which is critical for maintaining stable references in_parents.- Test Suite:
Performance: Adjusted overhead thresholds (to 500x) to realistically reflect the cost of recursive Python-based wrapping versus C-based Pydantic assignment.
Fuzzing: Constrained Hypothesis strategies in
test_stress.pyto generate strictly 64-bit signed integers, aligning withorjsonand SQLite limits.
Fixed¶
Serialization: Fixed
_pickle.PicklingErrorwhen using local classes in tests by moving test models to the global scope.SQLAlchemy 2.0: Fixed
InvalidRequestErrorin integration tests by ensuring models inherit from a subclass ofDeclarativeBase, notDeclarativeBasedirectly.Integration: Resolved
DetachedInstanceErrorin Pickle workflows by ensuring attributes are eager-loaded beforesession.expunge().Pydantic V2: Fixed a regression where
__getstate__failed to clean up_parentshidden inside Pydantic’s nested__dict__state structure.
[0.5.1] - 2025-12-18¶
A release focused on rigorous testing, cross-database compatibility, and extending support for non-Pydantic models.
Added¶
Testing: Integrated Hypothesis for property-based testing. The suite now fuzzes thousands of edge cases, including deep nesting, Unicode sequences, and large integers.
Utilities: Added
sqlalchemy_utilshelper module withcreate_sync_engineandcreate_async_engine. These helpers automatically configureorjsonas the serializer/deserializer, ensuring correct behavior across different SQL dialects (SQLite/Postgres).Architecture: Officially confirmed and tested support for Python Dataclasses and Attrs (via
MutableMixinand Identity Hashing).CI/CD: Added comprehensive stress tests (
tests/test_stress.py) verifying concurrency safety, rollback integrity, and memory stability under load.
Changed¶
Serialization:
orjsonis now the serialization engine. This provides significant performance gains but introduces a strict 64-bit signed integer limit (-2^63 to 2^63-1).Validation:
MutableMixinnow performs a “short-circuit” identity check before marking objects as dirty. Ifnew_value is old_value, the update is skipped to reduce DB overhead.Documentation: Major README overhaul. Added sections on “Under the Hood” architecture, performance benchmarks, and specific caveats regarding
orjsoninteger limits.
Fixed¶
Testing: Resolved
sqlite3.OperationalError: no such tablein tests by enforcingStaticPoolfor in-memory SQLite databases during Hypothesis runs.Compatibility: Fixed
TypeErrorwhen usingorjsonwith SQLAlchemy on SQLite (bytes vs string mismatch) by adding an automatic decoding layer insqlalchemy_utils.
[0.5.0] - 2025-12-18¶
A major release focused on stability, security, and improved Developer Experience (DX).
Added¶
Logging: Implemented structured logging (DEBUG/WARNING/ERROR levels) in
ModelTypeandMutableMixinto facilitate production debugging without side effects on import.Safety: Added protection against infinite recursion and DoS attacks via deep JSON nesting. Default limit: 100 levels (configurable via
_max_nesting_depth).Typing: Added
py.typedmarker file tosqlatypemodel/to support strict type checking (mypy) in user code.Performance: Optimized
__setattr__for atomic types (int,str,bool,float,NoneType,bytes,complex,frozenset) — they now skip the wrapping phase entirely, reducing overhead.
Changed¶
Error Handling: The
safe_changedmethod no longer swallows critical errors. Expected errors (e.g., dead weakrefs) are logged as DEBUG, while unexpected failures are logged as ERROR with tracebacks.Registration: Enforced stricter logic in
__init_subclass__. Theassociateclass must now inherit fromModelType. Custom types require manual registration viaassociate_with.Versioning: Package version is now resolved dynamically via
importlib.metadata, eliminating the risk of mismatch betweenpyproject.tomland__init__.py.
Fixed¶
Pydantic V2 Compatibility: Fixed a critical issue where
MutableMixinintercepted Pydantic V2 internal attributes (e.g.,model_fields), causing conflicts during model initialization.Critical Bug: Resolved version mismatch
Performance: Fixed potential O(N) complexity in collection change detection. It now uses strict identity checks (O(1)) for lists and dicts.