Tracks the upstream linopy change needed to drop the temporary linopy_yaml.Model subclass (see #5) and return to the monkey-patch + WeakKeyDictionary design described in SPEC.md.
Close this issue when the upstream PR lands in a released linopy version and linopy_yaml has migrated.
Problem
linopy.Model declares __slots__ but does not include __weakref__, which prevents any external registry from tracking Model instances.
import linopy, weakref
m = linopy.Model()
weakref.ref(m)
# TypeError: cannot create weak reference to 'Model' object
Use case
Third-party extensions (e.g. accessor-style libraries that add m.foo.<method>()) need per-instance storage without polluting Model's own slots or adding __dict__. The standard Python pattern is a WeakKeyDictionary keyed by the instance, so entries are garbage-collected with the model. That requires the class to be weakref-able.
Proposed change
class Model:
__slots__ = (
"_variables", "_constraints", ...,
"__weakref__", # add
)
Trade-offs
- Adds one pointer per instance (~8 bytes). No behavioral change.
- No API commitment or new public surface.
- Enables external extension patterns without requiring users to subclass
Model.
Compatibility
The change is strictly additive. Existing code that does not touch weakref is unaffected. Pickling and copy/deepcopy are not impacted — __weakref__ is a runtime-only slot and is not serialized.
One narrow case to flag: any downstream subclass of linopy.Model that already declares __weakref__ in its own __slots__ would break at import with:
TypeError: __weakref__ slot disallowed: either we already got one, or __itemsize__ != 0
One-line fix on the subclass side; unlikely to be common but worth noting in release notes.
Upstream link
Fill in once the linopy issue/PR is filed.
Tracks the upstream linopy change needed to drop the temporary
linopy_yaml.Modelsubclass (see #5) and return to the monkey-patch +WeakKeyDictionarydesign described inSPEC.md.Close this issue when the upstream PR lands in a released linopy version and
linopy_yamlhas migrated.Problem
linopy.Modeldeclares__slots__but does not include__weakref__, which prevents any external registry from trackingModelinstances.Use case
Third-party extensions (e.g. accessor-style libraries that add
m.foo.<method>()) need per-instance storage without pollutingModel's own slots or adding__dict__. The standard Python pattern is aWeakKeyDictionarykeyed by the instance, so entries are garbage-collected with the model. That requires the class to be weakref-able.Proposed change
Trade-offs
Model.Compatibility
The change is strictly additive. Existing code that does not touch
weakrefis unaffected. Pickling andcopy/deepcopyare not impacted —__weakref__is a runtime-only slot and is not serialized.One narrow case to flag: any downstream subclass of
linopy.Modelthat already declares__weakref__in its own__slots__would break at import with:One-line fix on the subclass side; unlikely to be common but worth noting in release notes.
Upstream link
Fill in once the linopy issue/PR is filed.