code: def unmarshal_dict(
      obj,
      cls,
      allow_extra_keys=True,
      ctor=None,
  ):
      
      if not ctor:
          ctor = cls
      args = init_args(ctor)
      obj = key_swap(obj, cls, False)
      kwargs = {k: v for k, v in obj.items() if k in args}
  
      # If either is set to False, do not allow extra keys
      # to be present in obj but not in cls.__init__
      allow_extra_keys = (
          getattr(cls, '_unmarshal_allow_extra_keys', True)
          and
          allow_extra_keys
      )
  
      if not allow_extra_keys and len(obj) > len(kwargs):
          diff = {k: v for k, v in obj.items() if k not in args}
          raise ExtraKeysError(cls, diff)
  
      try:
          return ctor(**kwargs)
      except ExtraKeysError as ex:
          raise ex
      except Exception as ex:
          raise InitArgsError(
              cls,
              args,
              kwargs,
              ex,
          )
docs: Unmarshal @obj into @cls
  
      Args:
          obj:              dict, The dict to unmarshal into @cls
          cls:              type, The class to unmarshal into
          allow_extra_keys: bool, False to raise an exception when extra
                            keys are present, True to ignore
      Returns:
          instance of @cls
      Raises:
          ExtraKeysError: If allow_extra_keys == False, and extra keys
                          are present in @obj and not in @cls.__init__
          ValueError:     If @cls.__init__ does not contain a self argument