def set_contained(value, name, parent): # Set contained information of schema.Object if IContained.providedBy(value): value.__name__ = name value.__parent__ = aq_base(parent) # Set contained information of schema.List|Tuple(value_type=Object) if isinstance(value, list) or isinstance(value, tuple): for item in value: if IContained.providedBy(item): item.__name__ = name item.__parent__ = aq_base(parent)
def containedEvent(object, container, name=None): """Establish the containment of the object in the container. """ if not IContained.providedBy(object): if ILocation.providedBy(object): zope.interface.alsoProvides(object, IContained) else: object = ContainedProxy(object) oldparent = object.__parent__ oldname = object.__name__ if oldparent is container and oldname == name: # No events return object, None object.__parent__ = container object.__name__ = name if oldparent is None or oldname is None: event = ObjectAddedEvent(object, container, name) else: event = ObjectMovedEvent(object, oldparent, oldname, container, name) return object, event
def start(self, contributor, starttime, message, history, object_): """Parameters: object_: object to be removed. history: the workflow history of this object.""" self.contributor = contributor self.starttime = starttime self.message = message self.object_ = object_ self.history = history # assert that object is removable, i.e. implements IRemovable if not interfaces.IRemovable.providedBy(object_): raise ProcessError( _( 'iremovable-not-provided', u"Unremovable database item. (IRemovable interface not provided.)" )) if interfaces.IFixed.providedBy(object_): raise ProcessError( _('ifixed-provided', u"Database item is fixed and can't be removed.")) #TODO: add some more ways to remove the object if not (IContained.providedBy(object_) or 1 == 2): raise ProcessError( _( 'wfmc-remove-unremovable', u"Unremovable database item. (Could not determine a way who to remove item.)" )) self._appendToWorkList()
def test_interface_providing(events): """If the object implements `ILocation`, but not `IContained`, set it's `__parent__` and `__name__` attributes *and* declare that it implements `IContained`. """ container = {} item = Location() assert not IContained.providedBy(item) setitem(container, container.__setitem__, u'l', item) assert container[u'l'] is item assert item.__parent__ is container assert item.__name__ == u'l' assert IContained.providedBy(item) # We get added and modification events: assert len(events) == 2 event = events.popleft() assert IObjectAddedEvent.providedBy(event) event = events.popleft() assert IObjectModifiedEvent.providedBy(event) # If the object doesn't even implement `ILocation`, put a # `ContainedProxy` around it: item = [] setitem(container, container.__setitem__, u'i', item) assert container[u'i'] == [] assert not container[u'i'] is item item = container[u'i'] assert item.__parent__ is container assert item.__name__ == u'i' assert IContained.providedBy(item) event = events.popleft() assert IObjectAddedEvent.providedBy(event) event = events.popleft() assert IObjectModifiedEvent.providedBy(event)
def finish(self, remove): self.schema['remove'].validate(remove) if remove == 'remove': # assert that the item is still not fixed. if interfaces.IFixed.providedBy(self.object_): raise ProcessError( _('ifixed-provided', u"Database item is fixed and can't be removed.")) # assert that the item asked to be removed is not under # control of other workflow processes similars = [ item for item in interfaces.ISimilarWorkItems( self).getSimilarWorkItems() ] if similars: raise ProcessError( _( 'wfmc-remove-still-similar', u"Failed to remove the object. The database item is still under control of other workflow processes. These must be finished first." )) # assert that the item asked to be removed has no # relations to other items in the database. if len(self.findRelationTokens()) > 0: raise ProcessError( _( 'wfmc-remove-still-relations', u"Failed to remove the object. The database item still has relations." )) # for contained item del it on container if IContained.providedBy(self.object_): container = self.object_.__parent__ del container[self.object_.__name__] else: pass #TODO: add some more ways to remove the object # we remove the work item on remove=='postpone', too. It gets # added by start again. self._removeFromWorkList() self.participant.activity.workItemFinished(self, remove, self.history, self.object_)
def traverse(self, name, ignored): result = None if self.request is not None: result = path_adapter(self.context, self.request, name) if result is None: # Look for the single-adapter. Or raise location error result = super(adapter_request, self).traverse(name, ignored) # Some sanity checks on the returned object # pylint: disable=unused-variable __traceback_info__ = result, self.context, result.__parent__, result.__name__ assert IContained.providedBy(result) assert result.__parent__ is not None if result.__name__ is None: result.__name__ = name assert result.__name__ == name return result
def containedEvent(object, container, name=None): # pylint:disable=redefined-builtin """Establish the containment of the object in the container The object and necessary event are returned. The object may be a `ContainedProxy` around the original object. The event is an added event, a moved event, or None. If the object implements `IContained`, simply set its ``__parent__`` and ``__name__`` attributes: >>> container = {} >>> item = Contained() >>> x, event = containedEvent(item, container, u'foo') >>> x is item True >>> item.__parent__ is container True >>> item.__name__ u'foo' We have an added event: >>> event.__class__.__name__ 'ObjectAddedEvent' >>> event.object is item True >>> event.newParent is container True >>> event.newName u'foo' >>> event.oldParent >>> event.oldName Now if we call contained again: >>> x2, event = containedEvent(item, container, u'foo') >>> x2 is item True >>> item.__parent__ is container True >>> item.__name__ u'foo' We don't get a new added event: >>> event If the object already had a parent but the parent or name was different, we get a moved event: >>> x, event = containedEvent(item, container, u'foo2') >>> event.__class__.__name__ 'ObjectMovedEvent' >>> event.object is item True >>> event.newParent is container True >>> event.newName u'foo2' >>> event.oldParent is container True >>> event.oldName u'foo' If the *object* implements `ILocation`, but not `IContained`, set its ``__parent__`` and ``__name__`` attributes *and* declare that it implements `IContained`: >>> from zope.location import Location >>> item = Location() >>> IContained.providedBy(item) False >>> x, event = containedEvent(item, container, 'foo') >>> x is item True >>> item.__parent__ is container True >>> item.__name__ 'foo' >>> IContained.providedBy(item) True If the *object* doesn't even implement `ILocation`, put a `ContainedProxy` around it: >>> item = [] >>> x, event = containedEvent(item, container, 'foo') >>> x is item False >>> x.__parent__ is container True >>> x.__name__ 'foo' Make sure we don't lose existing directly provided interfaces. >>> from zope.interface import Interface, directlyProvides >>> class IOther(Interface): ... pass >>> from zope.location import Location >>> item = Location() >>> directlyProvides(item, IOther) >>> IOther.providedBy(item) True >>> x, event = containedEvent(item, container, 'foo') >>> IOther.providedBy(item) True """ if not IContained.providedBy(object): if ILocation.providedBy(object): zope.interface.alsoProvides(object, IContained) else: object = ContainedProxy(object) oldparent = object.__parent__ oldname = object.__name__ if oldparent is container and oldname == name: # No events return object, None object.__parent__ = container object.__name__ = name if oldparent is None or oldname is None: event = ObjectAddedEvent(object, container, name) else: event = ObjectMovedEvent(object, oldparent, oldname, container, name) return object, event
def contained(obj, root, name=None): if not IContained.providedBy(obj): obj = ContainedProxy(obj) obj.__parent__ = root obj.__name__ = name return obj
def containedEvent(object, container, name=None): """Establish the containment of the object in the container The object and necessary event are returned. The object may be a `ContainedProxy` around the original object. The event is an added event, a moved event, or None. If the object implements `IContained`, simply set its `__parent__` and `__name__` attributes: >>> container = {} >>> item = Contained() >>> x, event = containedEvent(item, container, u'foo') >>> x is item True >>> item.__parent__ is container True >>> item.__name__ u'foo' We have an added event: >>> event.__class__.__name__ 'ObjectAddedEvent' >>> event.object is item True >>> event.newParent is container True >>> event.newName u'foo' >>> event.oldParent >>> event.oldName Now if we call contained again: >>> x2, event = containedEvent(item, container, u'foo') >>> x2 is item True >>> item.__parent__ is container True >>> item.__name__ u'foo' We don't get a new added event: >>> event If the object already had a parent but the parent or name was different, we get a moved event: >>> x, event = containedEvent(item, container, u'foo2') >>> event.__class__.__name__ 'ObjectMovedEvent' >>> event.object is item True >>> event.newParent is container True >>> event.newName u'foo2' >>> event.oldParent is container True >>> event.oldName u'foo' If the `object` implements `ILocation`, but not `IContained`, set its `__parent__` and `__name__` attributes *and* declare that it implements `IContained`: >>> from zope.location import Location >>> item = Location() >>> IContained.providedBy(item) False >>> x, event = containedEvent(item, container, 'foo') >>> x is item True >>> item.__parent__ is container True >>> item.__name__ 'foo' >>> IContained.providedBy(item) True If the `object` doesn't even implement `ILocation`, put a `ContainedProxy` around it: >>> item = [] >>> x, event = containedEvent(item, container, 'foo') >>> x is item False >>> x.__parent__ is container True >>> x.__name__ 'foo' Make sure we don't lose existing directly provided interfaces. >>> from zope.interface import Interface, directlyProvides >>> class IOther(Interface): ... pass >>> from zope.location import Location >>> item = Location() >>> directlyProvides(item, IOther) >>> IOther.providedBy(item) True >>> x, event = containedEvent(item, container, 'foo') >>> IOther.providedBy(item) True """ if not IContained.providedBy(object): if ILocation.providedBy(object): zope.interface.alsoProvides(object, IContained) else: object = ContainedProxy(object) oldparent = object.__parent__ oldname = object.__name__ if oldparent is container and oldname == name: # No events return object, None object.__parent__ = container object.__name__ = name if oldparent is None or oldname is None: event = ObjectAddedEvent(object, container, name) else: event = ObjectMovedEvent(object, oldparent, oldname, container, name) return object, event
def test_contained_event(): container = {} item = Contained() x, event = containedEvent(item, container, u'foo') assert x is item assert item.__parent__ is container assert item.__name__ == u'foo' assert event.__class__.__name__ == 'ObjectAddedEvent' assert event.object is item assert event.newParent is container assert event.newName == u'foo' assert event.oldParent is None assert event.oldName is None # Event is not triggered twice. x2, event = containedEvent(item, container, u'foo') assert x2 is item assert item.__parent__ is container assert item.__name__ == u'foo' assert not event # Moved event x, event = containedEvent(item, container, u'foo2') assert event.__class__.__name__ == 'ObjectMovedEvent' assert event.object is item assert event.newParent is container assert event.newName == u'foo2' assert event.oldParent is container assert event.oldName == u'foo' # Ilocation enrichment item = Location() assert not IContained.providedBy(item) x, event = containedEvent(item, container, 'foo') assert x is item assert item.__parent__ is container assert item.__name__ == 'foo' assert IContained.providedBy(item) # Containment proxy item = [] x, event = containedEvent(item, container, 'foo') assert not x is item assert x.__parent__ is container assert x.__name__ == 'foo' # Make sure we don't lose existing directly provided interfaces. from zope.interface import Interface, directlyProvides class IOther(Interface): pass item = Location() directlyProvides(item, IOther) assert IOther.providedBy(item) x, event = containedEvent(item, container, 'foo') assert IOther.providedBy(item)
def save_form( # noqa: C901 (this has gotten quite complex) form, data, submission, default_values=False, force=False, ): changes = {} for name, field in form.fields.items(): if name == 'schema': continue elif name not in data and default_values: value = field.field.default adapter = queryMultiAdapter( ( form.context, form.request, form, field.field, form.widgets[name], ), IValue, name='default', ) if adapter: value = adapter.get() elif name not in data: continue else: value = data[name] if value is NOT_CHANGED: continue # Set contained information of schema.Object if IContained.providedBy(value): value.__name__ = name value.__parent__ = aq_base(submission) # Set contained information of schema.List|Tuple(value_type=Object) if isinstance(value, list) or isinstance(value, tuple): for item in value: if IContained.providedBy(item): item.__name__ = name item.__parent__ = aq_base(submission) if force: setattr(submission, name, value) elif changedField(field.field, value, context=submission): # Only update the data, if it is different dm = getMultiAdapter((submission, field.field), IDataManager) dm.set(value) # Record the change using information required later changes.setdefault(dm.field.interface, []).append(name) try: for group in form.groups: changes.update( save_form(group, data, submission, default_values, force), ) except AttributeError: pass return changes