code: def rollback(
      model: Model, undo: Optional[Callable] = None, *args, **kwargs
  ) -> Iterator[list]:
      
      with hold(model, *args, **kwargs) as events:
          try:
              yield events
          except Exception as error:
              if undo is not None:
                  with mute(model):
                      undo(model, tuple(events), error)
              events.clear()
              raise
docs: Withold events if an error occurs.
  
      Generall operate
  
      Parameters:
          model:
              The model object whose change events may be witheld.
          undo:
              An optional function for reversing any changes that may have taken place.
              Its signature is ``(model, events, error)`` where ``model`` is the given
              model, ``event`` is a tuple of all the events that took place, and ``error``
              is the exception that was riased. Any changes that you make to the model
              within this function will not produce events.
  
      Examples:
  
          Simple supression of events:
  
          .. code-block:: python
  
              from spectate import mvc
  
              d = mvc.Dict()
  
              @mvc.view(d)
              def should_not_be_called(d, events):
                  # we never call this view
                  assert False
  
              try:
                  with mvc.rollback(d):
                      d["a"] = 1
                      d["b"]  # key doesn't exist
              except KeyError:
                  pass
  
          Undo changes for a dictionary:
  
          .. code-block:: python
  
              from spectate import mvc
  
              def undo_dict_changes(model, events, error):
                  seen = set()
                  for e in reversed(events):
                      if e.old is mvc.Undefined:
                          del model[e.key]
                      else:
                          model[e.key] = e.old
  
              try:
                  with mvc.rollback(d, undo=undo_dict_changes):
                      d["a"] = 1
                      d["b"] = 2
                      print(d)
                      d["c"]
              except KeyError:
                  pass
              print(d)
  
          .. code-block:: python
  
              {'a': 1, 'b': 2}
              {}