Extending the Data Model¶
MolPy's graph data model is backed directly by molrs. Atomistic and
CoarseGrain are native worlds; Atom, Bond, Bead, and the other Python
objects are live views over stable handles in those worlds.
Discuss before you build
A new stored node or relation kind changes the molrs schema, Rust graph algorithms, Python bindings, frame projection, and I/O formatters. Open a GitHub issue before implementing it.
What can be extended in Python¶
Python subclasses may add stateless conveniences around an existing native kind: constructor aliases, selection helpers, callbacks, display methods, and format-specific serialization. They must not create a second property store, endpoint list, or handle registry.
Use a graph factory to create data:
from molpy import Atomistic
mol = Atomistic(name="water")
oxygen = mol.def_atom(element="O", x=0.0, y=0.0, z=0.0)
hydrogen = mol.def_atom(element="H", x=0.96, y=0.0, z=0.0)
bond = mol.def_bond(oxygen, hydrogen)
assert mol.atoms[0] == oxygen
assert bond.endpoints == (oxygen, hydrogen)
Writes through a ref immediately update the native world. Collection properties
such as .atoms, .bonds, and .impropers are lazy handle collections: they
intern live views on integer access and support column-style field reads
(atoms["x"]) without building every view up front.
Adding a stored graph kind¶
There is intentionally no TypeBucket.register_type hook. A real new kind
requires, in order:
- Define its storage and relation arity in molrs.
- Teach native copy/merge/extract/topology and Frame projection about it.
- Expose a handle view and graph factory in
molrs.views. - Re-export that same object from
molpy.core; add only Python syntax sugar. - Update relevant readers/writers and add Rust, binding, and molpy integration tests.
If the concept is only an annotation, prefer a typed field on an existing node
or relation. For example, assembly sites use fields.SITE; they do not require
a new node class.
Checklist¶
- The data has one owner in molrs; no Python mirror or
_innerfacade. - Handles remain stable across live views and writes update the world.
- Native copy/merge/extract and Frame round trips cover the new kind.
- PyO3 exports and type stubs are updated before molpy uses the API.
- MolPy re-exports the native type or adds a true native subclass only.
- Rust, molrs-python, and molpy integration tests all pass.