def _jsonable2thrift_helper(jsonable, type_enum, spec_args, default, recursion_depth=0):
  """
  Recursive implementation method of jsonable2thrift.

  type_enum corresponds to TType.  spec_args is part of the
  thrift_spec explained in Thrift's code generator.  See
  compiler/cpp/src/generate/t_py_generator.cc .
  default is the default value.

  This method is aggressive about checking types and limits.
  It does not however warn about keys appearing in dictionaries
  that are not represented in the Thrift struct.

  Note that jsonable representations of Thrift objects
  are friendly to read, but they are not backwards-compatible,
  because they are indexed by field names, and not field ids.
  """
  if recursion_depth > MAX_RECURSION_DEPTH:
    raise Exception("Maximum recursion depth exceeded in jsonable2thrift.")

  if jsonable is None:
    return default

  def check_bits(jsonable, bits):
    """
    Helper function to check bounds.

    The Thrift IDL specifies how many bytes numbers can be, and always uses
    signed integers.  This makes sure that the Thrift struct that comes out
    conforms to that schema.
    """
    check_type(jsonable, (int, long))
    # For example, for 8 bits, this yields the range -128 to 127 (inclusive).
    min_val = -1 << (bits-1)
    max_val = (1 << (bits-1)) - 1
    assert min_val <= jsonable, "Value %d <= %d minimum value" % (jsonable, min_val)
    assert max_val >= jsonable, "Value %d >= %d maxium value" % (jsonable, max_val)

  def check_type(jsonable, expected):
    assert isinstance(jsonable, expected), "Value %s has wrong type.  Expected %s." % (repr(jsonable), repr(expected))

  if type_enum == TType.BOOL:
    check_type(jsonable, bool)
    return jsonable

  elif type_enum == TType.BYTE:
    check_bits(jsonable, 8)
    return jsonable

  elif type_enum == TType.I16:
    check_bits(jsonable, 16)
    return jsonable

  elif type_enum == TType.I32:
    check_bits(jsonable, 32)
    return jsonable

  elif type_enum == TType.I64:
    check_bits(jsonable, 64)
    return jsonable

  elif type_enum == TType.DOUBLE:
    check_type(jsonable, float)
    return jsonable

  elif type_enum == TType.STRING:
    assert isinstance(jsonable, basestring)
    return jsonable

  elif type_enum == TType.STRUCT:
    check_type(jsonable, dict)
    thrift_type, thrift_spec = spec_args
    out = thrift_type()
    # Recurse in, field-by-field
    for spec in thrift_spec:
      if spec is None:
        # thrift_spec is indexed by thrift tag id, so None shows up
        continue
      _, cur_type_enum, cur_name, cur_spec_args, cur_default = spec
      value = _jsonable2thrift_helper(jsonable.get(cur_name),
        cur_type_enum, cur_spec_args, cur_default, recursion_depth + 1)
      setattr(out, cur_name, value)
    return out

  elif type_enum == TType.MAP:
    check_type(jsonable, dict)
    key_type_enum, key_spec_args, val_type_enum, val_spec_args = spec_args
    out = dict()
    for k_jsonable, v_jsonable in jsonable.iteritems():
      k = _jsonable2thrift_helper(k_jsonable, key_type_enum, key_spec_args, None, recursion_depth + 1)
      v = _jsonable2thrift_helper(v_jsonable, val_type_enum, val_spec_args, None, recursion_depth + 1)
      out[k] = v
    return out

  elif type_enum == TType.SET:
    # JSON doesn't have native set; set is represented
    # as a map with values True.
    set_type_enum, set_spec_args = spec_args
    out = set()
    for k, v in jsonable.iteritems():
      assert v is True, "Expected set value to be True.  Got: %s" % repr(v)
      out.add(_jsonable2thrift_helper(k, set_type_enum, set_spec_args, None, recursion_depth + 1))
    return out

  elif type_enum == TType.LIST:
    check_type(jsonable, list)
    list_type_enum, list_spec_args = spec_args
    out = list()
    for x in jsonable:
      out.append(_jsonable2thrift_helper(x, list_type_enum, list_spec_args, None, recursion_depth + 1))
    return out

  else:
    raise Exception("Unrecognized type: %s.  Value was %s." % (repr(type_enum), repr(jsonable)))
dataset/ETHPy150Open cloudera/hue/desktop/core/src/desktop/lib/thrift_util.py/_jsonable2thrift_helper/original