Skip to content

Serializer: store classes as references, add aliases and schema versions - #48

Merged
nicholas9182 merged 4 commits into
devfrom
feature/serializer-type-references
Sep 29, 2026
Merged

nicholas9182 merged 4 commits into
devfrom
feature/serializer-type-references

Conversation

@0x1r1s

@0x1r1s 0x1r1s commented Sep 25, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

The serializer stores a class as a reference (its module path), never as code. This PR extends that approach so that SerializerMixin can save types and sets, and so that saved data stays readable after the code changes.

  1. Types, sets and keys. A class value is now saved as {'__type__': 'module.Class'} and resolved through the allowlist. Before this change, a class value became None with no error. set and frozenset are saved in sorted order, so equal sets give equal bytes. A class, an enum or a tuple can now be a dict key. Before this change, msgpack refused these keys.
  2. Moved classes. register_class_alias(old_path, new_path) loads old payloads after a class moves or is renamed. Aliases can form a chain. A cycle is refused. The allowlist check applies to the new path.
  3. Changed attributes. A class can set _schema_version and override _migrate(data, version). A load calls _migrate when the payload is older than the class. A payload that is newer than the class raises SchemaVersionError. Version 0 is not written, so the payloads of existing classes do not change.
  4. Deleted classes. A missing module or class raises MissingClassError (a ValueError). The message names the path and refers to register_class_alias.

PropagationMixin no longer calls _set_parent on a class value after a load.

Backward compatibility

  • I loaded each of the 73 objects in the OpenCell database and saved it again, with dev and with this branch. The bytes are the same for all 73. Each object loads again.
  • The new error classes are subclasses of ValueError, so code that catches ValueError around deserialize continues to work.

Tests

  • test/test_serializer_mixin.py: 28 new tests for type references, sets, aliases, missing classes and schema versions. The full steer-core suite passes.
  • The full steer-opencell-design suite passes with this branch.

Next step

steer-opencell-production uses these features to save machines. After this PR is merged and released, that package must raise its steer-core version bound.

- Store a class value as {'__type__': 'module.Class'} and resolve it through
  the allowlist. Before, a class value became None without an error.
- Serialize set and frozenset in sorted order. Accept a class, enum or tuple
  as a dict key.
- Add register_class_alias(old_path, new_path) so that payloads load after a
  class moves or is renamed.
- Add _schema_version, _migrate() and SchemaVersionError. Version 0 is not
  written, so existing payloads do not change.
- Raise MissingClassError when a payload names a class or module that the
  installed code does not have.
- PropagationMixin: do not call _set_parent on a class value.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

All contributors have signed the CLA. Thank you!
Posted by the CLA Assistant Lite bot.

@0x1r1s

0x1r1s commented Sep 25, 2026

Copy link
Copy Markdown
Collaborator Author

I have read the CLA Document and I hereby sign the CLA

github-actions Bot added a commit that referenced this pull request Sep 25, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
0x1r1s added a commit that referenced this pull request Sep 29, 2026
0.2.24 is already on PyPI and is now used by PR #48.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keep dev's {'__set__': True, 'items': [...]} set payload (released in
0.2.24) with sorted items; reader also accepts the list-valued form.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@nicholas9182
nicholas9182 merged commit fd5e107 into dev Sep 29, 2026
1 check passed
@0x1r1s
0x1r1s deleted the feature/serializer-type-references branch September 30, 2026 16:52
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.

2 participants