def pre_map(self, function): """ Iterates over layout objects pointed in `self.slice` executing `function` on them. It passes `function` penultimate layout object and the position where to find last one """ if isinstance(self.slice, slice): for i in range(*self.slice.indices(len(self.layout.fields))): function(self.layout, i) elif isinstance(self.slice, list): # A list of pointers Ex: [[[0, 0], 'div'], [[0, 2, 3], 'field_name']] for pointer in self.slice: position = pointer[0] # If it's pointing first level if len(position) == 1: function(self.layout, position[-1]) else: layout_object = self.layout.fields[position[0]] for i in position[1:-1]: layout_object = layout_object.fields[i] try: function(layout_object, position[-1]) except IndexError: # We could avoid this exception, recalculating pointers. # However this case is most of the time an undesired behavior raise DynamicError( "Trying to wrap a field within an already wrapped field, \ recheck your filter or layout")
def wrap_together(self, LayoutClass, *args, **kwargs): """ Wraps all layout objects pointed in `self.slice` together under a `LayoutClass` instance with `args` and `kwargs` passed. """ if isinstance(self.slice, slice): # The start of the slice is replaced start = self.slice.start if self.slice.start is not None else 0 self.layout.fields[start] = self.wrapped_object( LayoutClass, self.layout.fields[self.slice], *args, **kwargs ) # The rest of places of the slice are removed, as they are included in the previous for i in reversed(range(*self.slice.indices(len(self.layout.fields)))): if i != start: del self.layout.fields[i] elif isinstance(self.slice, list): raise DynamicError("wrap_together doesn't work with filter, only with [] operator")