code: def catch_nb_assignment(func):
      
  
      @wraps(func)
      def wrapper(self, *args, **kwargs):
          nb = kwargs.get('nb')
          if nb:
              # Reassign if executing notebook object was replaced
              self.nb = nb
          return func(self, *args, **kwargs)
  
      return wrapper
docs: Wrapper to catch `nb` keyword arguments
  
      This helps catch `nb` keyword arguments and assign onto self when passed to
      the wrapped function.
  
      Used for callback methods when the caller may optionally have a new copy
      of the originally wrapped `nb` object.