docs: def _update_attrs(nobj, oobj, exceptions=None, acornext=False):
      """Updates the attributes on `nobj` to match those of old, excluding the any
      attributes in the exceptions list.
      """
      success = True
      if (acornext and hasattr(oobj, "__acornext__")
          and oobj.__acornext__ is not None): # pragma: no cover
          target = oobj.__acornext__
      else:
          target = oobj
          
      for a, v in _get_members(target):
          if hasattr(nobj, a):
              #We don't want to overwrite something that acorn has already done.
              continue
          if a in ["__class__", "__code__", "__closure__"]:# pragma: no cover
              #These attributes are not writeable by design.
              continue
          
          if exceptions is None or a not in exceptions:
              try:
                  setattr(nobj, a, v)
              except TypeError:# pragma: no cover
                  #Some of the built-in types have __class__ attributes (for
                  #example) that we can't set on a function type. This catches
                  #that case and any others.
                  emsg = "_update_attrs (type): {}.{} => {}"
                  msg.err(emsg.format(nobj, a, target), 2)
                  pass
              except AttributeError:# pragma: no cover
                  #Probably a read-only attribute that we are trying to set. Just
                  #ignore it.
                  emsg = "_update_attrs (attr): {}.{} => {}"
                  msg.err(emsg.format(nobj, a, target), 2)
                  pass
              except ValueError:# pragma: no cover
                  emsg = "_update_attrs (value): {}.{} => {}"
                  msg.err(emsg.format(nobj, a, target), 2)
                  success = False
  
      return success