util.dirtyable module

Dirtyable: a mix-in for objects that need to know whether they’ve changed since they were last saved (a “dirty bit”), including through the objects they contain.

Created on Sep 11, 2026

Code author: Rob Kremer <robkremer@me.com>

class util.dirtyable.Dirtyable(**kwargs)

Bases: object

A mixin class for object needing a dirty bit, using setDirty() and isDirty()

__init__(**kwargs) → None

Set the _dirty property and initialize it to False.

Parameters:

kwargs (Any) – Passed on to super().__init__(). Dirtyable is normally one link in a longer chain of cooperative __init__ calls – eg: sn.view.graphics.vobjects.VObject combines it with Observer and ErrorReportingObject via multiple inheritance. Calling super().__init__(**kwargs) here (instead of simply returning) ensures whatever comes after Dirtyable in that particular class’s MRO still gets initialized, exactly once, with the constructor arguments meant for it, even though Dirtyable itself has no use for them. Not doing this used to silently strand every class listed after Dirtyable in such a chain – eg: ErrorReportingObject.__init__() never ran for any VObject, because Dirtyable.__init__() was the cooperative chain’s dead end.

_dirty: bool
setDirty(dirty: bool = True)

An object is dirty if it has been modified and should probably be saved on exit. This should be called from all methods that modify the state of this object.

Container classes should override this method to clear all child Dirtyables if the dirty bit is being cleared (presumably after a save opertation) with something like the following:

if not dirty:
  obj:T
  for obj in self.values():  # LOCAL attributes only -- an inherited Attribute belongs to (and is tracked dirty by) its owning super object, not this one
    if obj.isDirty():
      obj.setDirty(False)
super().setDirty(dirty)
Parameters:
  • value (bool) – (default True) The value to set dirty to.

  • dirty (bool)

isDirty() → bool

Returns True iff the object has been modified and should probably be saved on exit.

Container classes should override this method to check all child Dirtyables if the its own dirty bit not already set with something like the following:

if super().isDirty():
  return True
obj:T
for obj in self.values():  # LOCAL attributes only -- see setDirty()
  if obj.isDirty():
    super().setDirty(True)
    return True
return False
Returns:

True iff this object is dirty.

Return type:

bool