code: def load(cls, data, promote=False):
          
          t = type(data)
  
          if t == cls:
              # same class, create new copy
              return cls({k: cls.load(v, promote)
                          for k, v in data.__dict__.items()})
  
          elif isinstance(data, cls):
              # child class, always use directly
              return data.copy()
  
          elif isinstance(data, Ent):
              # parent class, promote or preserve
              if promote:
                  return cls({k: cls.load(v, promote)
                              for k, v in data.__dict__.items()})
              else:
                  return data.copy()
  
          elif t not in SAFE_TYPES:
              return None
  
          elif t in (tuple, list, set):
              return t(cls.load(i) for i in data)
  
          elif t == dict:
              return cls({k: cls.load(v) for k, v in data.items()})
  
          else:
              return data
docs: Create a new ent from an existing value.  The value must either
          be an instance of Ent, or must be an instance of SAFE_TYPES.  If
          the value is a base type (bool, int, string, etc), it will just be
          returned.  Iterable types will be loaded recursively, transforming
          dictionaries into Ent instances, but otherwise maintaining the
          hierarchy of the input data.