Interface Definitions¶
Immutable Interfaces.
- interface shoobx.immutable.interfaces.IImmutable¶
Immutable Object
In an immutable object no data can be modified. To modify state, a copy of the object must be created into which the changes are applied.
When trying to modify an attribute of a locked immutable, an AttributeError is raised with the message saying that the attribute cannot be set. The only exceptions are internal attributes which are determined using the __im_is_internal_attr__(name) -> bool method.
Immutables are created using the __im_create__() context manager in the following way:
with Immutable.__im_create__() as factory: im = factory(attr=value)
Immutables are updated using the __im_update__() context manager in the following way:
with im.__im_update__() as im2: im2.attr = value2
In the example above, im is not modified and all changes are applied to im2.
The algorithm works as follows:
The __im_update__() method is used to create a context manager.
Upon entering the context manager, a clone of the original immutable is created and returned as context.
The clone is in the transient state, allowing all data to be modified. Note that modifications can be made at any depth in the object.
Upon exiting the context manager, the clone is put in the locked state.
Internally, updating deeply nested objects is managed by assigning a mode to the immutable. The master mode describes an immutable that can be updated while a slave (sub-object) is updated as part of its master. The following rules apply:
All immutable sub-objects must be slave immutables.
A master immutable cannot be assigned or added to another immutable, whether that’s a master or slave.
Only master immutables can call __im_update__().
Any immutable object can only have sub-objects that are also immutable or can be made immutable upon assignment.[1]
- ..[1] During initialization all class attributes are checked to be
immutable or are converted to immutables. On assignment, any mutable object is converted into an immutable object. If convertsion to an immutable object fails, a ValueError error is raised.
Conversion of mutable to immutable objects:
All immutable objects are ignored. These object include all Python core immutables and any object providing this IImmutable interface.
A conversion from lists, dicts and sets is provided.
A mutable object can implement the __im_get__() method to provide an immutable version of itself. Note: __im_get__() must NOT return the same object instance!
- __im_mode__¶
Immutable Mode
- Implementation
zope.schema.Choice
- Read Only
False
- Required
True
- Default Value
‘master’
- __im_state__¶
Immutable State
- Implementation
zope.schema.Choice
- Read Only
False
- Required
True
- Default Value
‘transient’
- __im_conform__(object)¶
Get an immutable version of the object.
This method converts the given object into its immutable self.
The return value will either be a core immutable object or an object implementing the IImmutable interface. If the latter is returned, it must be in IM_MODE_SLAVE mode and in the IM_STATE_TRANSIENT state.
When having an IImmutable object, we must ensure that the result is in the transient state. Thus, if the immutable is already in the transient state, just return it, otherwise create a transient clone of it.
This method is intended for internal use only and should only be called for sub-objects while adding them to the immutable. The resulting immutable must also be in the IM_STATE_TRANSIENT state.
Raises a ValueError exception if the object cannot be converted.
- __im_clone__()¶
Return a clone of itself.
Important: This method produces a deep clone of itself in transient mode.
- __im_set_state__(state)¶
Set state on the object and all sub objects
Sub-objects are objects in attributes, dict values, list items, etc.
- __im_finalize__()¶
Finalize the object.
The immutable and all its sub-objects are being locked to disallow any further write access.
- __im_create__(cls, mode=None, finalize=True, *create_args, **create_kw)¶
Returns a context manager allowing the cls class to be instantiated
Within the context you can set any attribute on the object, call any method to setup the initial state. Exiting the context shall finalize the object.
mode: gets set on the object as it’s __im_mode__
finalize: the object gets finalized at the very end
create_args, create_kw: get passed to cls.__im_after_create__ right after cls.__init__ is called, thus allowing to set e.g. creator before the object is finalized
- __im_after_create__(*args, **kw)¶
Hook called right after __im_create__ factory called __init__
The just created object is still in transient state.
- __im_before_update__(clone)¶
Hook called before __im_update__()
It is called after a clone in transient state has been created and self is retired.
- __im_after_update__(clone)¶
Hook called at the end of __im_update__().
This method is called while exiting the context manager but before finalizing the clone. Thus, the clone object is still in transient state.
- __im_update__()¶
Returns a context manager allowing the context to be modified.
If the immutable is initially in the locked state, then a clone in the transient state is created and provided as context.
If the immutable is already in the transient state, then the object itself is returned.
- __setattr__(name, value)¶
Set the new attribute value for the given name.
If the value is not an immutable, an AttributeError will be raised.
- interface shoobx.immutable.interfaces.IImmutableObject¶
Extends:
shoobx.immutable.interfaces.IImmutable
Immutable Type.
Specific interface to mark general immutable classes.
All immutable objcets will support two constructor arguments implicitly:
im_finalize = True: When true, the object will be created in the locked state. That is particularly useful when all data is set inside the constructor.
im_mode = None: If a mode is provided, the created immutable will be set to this mode.
- interface shoobx.immutable.interfaces.IRevisionedImmutableManager¶
Revisioned immutable contianer.
This interface is agnostic on how the underlying object is identified from the revision. A sensible implementation is to have a deignated attribute for the name of the object.
The API was also designed to support efficient revision management when working large numbers of revisions. This adds some complexities for simple implementations.
- getCurrentRevision(obj)¶
Get the currently active revision of the object.
If no revision or active revision is found for the object, None is returned.
- getNumberOfRevisions(obj)¶
Return the total number of revisions.
- getRevisionHistory(obj, creator=None, comment=None, startBefore=None, startAfter=None, batchStart=0, batchSize=None, reversed=False)¶
Returns an iterable of object revisions in chronological order.
The following arguments filter the search results:
creator: The creator of the revision must match the argument.
comment: The comment must contain the argument as a substring.
startBefore: The revision must start before the given date/time.
startAfter: The revision must start after the given date/time.
The following arguments affect the ordering:
- reversed: When true, the history will be return in reverse
chronological order, specifically the latest revision is listed first.
The following arguments apply batching:
batchStart: The index at which to start the batch.
- batchSize: The size the of the batch. It is thus the max length of
the iterable.
- addRevision(new, old=None)¶
Add a new revision.
This method should be implemented to allow a simple append operation to the revision history.
It must assign the __im_start_on__ attribute of the new revision to the current date/time. Also, the __im_manager__ attribute will be set to this IRevisionedImmutableManager instance. It is assumed and may be asserted that the new revision is already locked.
If the old revision is None, then a new revision history will be created and the new revision is the origin revision.
If the old revision is specified, the old revision’s __im_end_on__ date/time is set to the new revision’s __im_start_on__ date/time and the state is set to the IM_STATE_RETIRED state.
- rollbackToRevision(revision, activate=True)¶
Rollback to the given revision making it the newest one.
Properly roll back to a previous revision.
The revision must exist in the revision history. Otherwise a KeyError is raised.
Find all revisions with a start timestamp greater than the revision’s start timestamp.
If no revisions are found, the revision is already the latest one.
Remove all found revisions.
If the activate flag is set, then set the revision’s end timestamp should be set to None.
- interface shoobx.immutable.interfaces.IRevisionedImmutable¶
Extends:
shoobx.immutable.interfaces.IImmutable
Revisioned Immutable Object
This object represents one revision on an immutable object in the revision history of the immutable.
While not strictly necessary, the revisioned immutable works best in combination with a manager. If __im_manager__ is set, callbacks will be made to the manager to notify it of any new revisions using the addRevision() method.
- __im_state__¶
Immutable State
- Implementation
zope.schema.Choice
- Read Only
False
- Required
True
- Default Value
‘transient’
- __im_version__¶
Version
The version of the immutable revision. It is used to establish chronological order.
- Implementation
zope.schema.Int
- Read Only
False
- Required
True
- Default Value
0
- Allowed Type
- __im_start_on__¶
Active Start Timestamp
Timestamp describing the moment at which the revision became active.
- Implementation
zope.schema.Datetime
- Read Only
False
- Required
True
- Default Value
None
- Allowed Type
- __im_end_on__¶
Active End Timestamp
Timestamp describing the moment at which the revision retired. If the value is None, the revision is still active.
- Implementation
zope.schema.Datetime
- Read Only
False
- Required
False
- Default Value
None
- Allowed Type
- __im_creator__¶
Revision Creator
A string representing the creator of the revision. It is up to the application to provide further meaning to this field.
- Implementation
zope.schema.TextLine
- Read Only
False
- Required
False
- Default Value
None
- Allowed Type
- __im_comment__¶
Revision Comment
A himan readable comment of the revision.
- Implementation
zope.schema.Datetime
- Read Only
False
- Required
False
- Default Value
None
- Allowed Type
- __im_manager__¶
Revisioned Immutable Manager
If set, callbacks will be made to notify the manager of changes.
- Implementation
zope.schema.Object
- Read Only
False
- Required
False
- Default Value
None
- Must Provide
- __im_update__(creator=None, comment=None)¶
Returns a context manager providing a clone that can be edited.
If the immutable is already in the transient state, then the object itself is returned. All arguments to the method are ignored.
If a clone is created, then the __im_creator__ and __im_comment__ attributes will be set.
If __im_manager__ is set, __im_manager__.addRevision(clone, old=self) must be called.
- __im_after_create__(creator=None, comment=None)¶
Hook called right after __im_create__ factory called __init__
The just created object is still in transient state.