code: def cast(obj):
      
      if isinstance(obj, dict):
          return dict((cast(k), cast(v)) for k, v in iteritems(obj))
      if isinstance(obj, (list, tuple)):
          return [cast(v) for v in obj]
      if isinstance(obj, PASSTHROUGH):
          return obj
      if isinstance(obj, mitogen.core.UnicodeType):
          return mitogen.core.UnicodeType(obj)
      if isinstance(obj, mitogen.core.BytesType):
          return mitogen.core.BytesType(obj)
  
      raise TypeError("Cannot serialize: %r: %r" % (type(obj), obj))
docs: Many tools love to subclass built-in types in order to implement useful
      functionality, such as annotating the safety of a Unicode string, or adding
      additional methods to a dict. However, cPickle loves to preserve those
      subtypes during serialization, resulting in CallError during :meth:`call
      <mitogen.parent.Context.call>` in the target when it tries to deserialize
      the data.
  
      This function walks the object graph `obj`, producing a copy with any
      custom sub-types removed. The functionality is not default since the
      resulting walk may be computationally expensive given a large enough graph.
  
      See :ref:`serialization-rules` for a list of supported types.
  
      :param obj:
          Object to undecorate.
      :returns:
          Undecorated object.