def _decode_union_dict(data_type, obj, strict):
    if ".tag" not in obj:
        raise bv.ValidationError("missing '.tag' key")
    tag = obj[".tag"]
    if not isinstance(tag, six.string_types):
        raise bv.ValidationError("tag must be string, got %s" % bv.generic_type_name(tag))

    if tag not in data_type.definition._tagmap:
        if not strict and data_type.definition._catch_all:
            return data_type.definition._catch_all, None
        else:
            raise bv.ValidationError("unknown tag '%s'" % tag)

    val_data_type = data_type.definition._tagmap[tag]
    if isinstance(val_data_type, bv.Nullable):
        val_data_type = val_data_type.validator
        nullable = True
    else:
        nullable = False

    if isinstance(val_data_type, bv.Void):
        if tag in obj:
            if obj[tag] is not None:
                raise bv.ValidationError("expected null, got %s" % bv.generic_type_name(obj[tag]))
        for key in obj:
            if key != tag and key != ".tag":
                raise bv.ValidationError("unexpected key '%s'" % key)
        val = None
    elif isinstance(val_data_type, (bv.Primitive, bv.List, bv.StructTree, bv.Union)):
        if tag in obj:
            raw_val = obj[tag]
            try:
                val = _json_compat_obj_decode_helper(val_data_type, raw_val, strict, False)
            except bv.ValidationError as e:
                e.add_parent(tag)
                raise
        else:
            # Check no other keys
            if nullable:
                val = None
            else:
                raise bv.ValidationError("missing '%s' key" % tag)
        for key in obj:
            if key != tag and key != ".tag":
                raise bv.ValidationError("unexpected key '%s'" % key)
    elif isinstance(val_data_type, bv.Struct):
        if nullable and len(obj) == 1:  # only has a .tag key
            val = None
        else:
            # assume it's not null
            raw_val = obj
            try:
                val = _json_compat_obj_decode_helper(val_data_type, raw_val, strict, False)
            except bv.ValidationError as e:
                e.add_parent(tag)
                raise
    else:
        assert False, type(val_data_type)
    return tag, val
def _decode_union_old(data_type, obj, strict):
    """
    The data_type argument must be a Union.
    See json_compat_obj_decode() for argument descriptions.
    """
    val = None
    if isinstance(obj, six.string_types):
        # Union member has no associated value
        tag = obj
        if tag in data_type.definition._tagmap:
            val_data_type = data_type.definition._tagmap[tag]
            if not isinstance(val_data_type, (bv.Void, bv.Nullable)):
                raise bv.ValidationError(
                    "expected object for '%s', got symbol" % tag)
        else:
            if not strict and data_type.definition._catch_all:
                tag = data_type.definition._catch_all
            else:
                raise bv.ValidationError("unknown tag '%s'" % tag)
    elif isinstance(obj, dict):
        # Union member has value
        if len(obj) != 1:
            raise bv.ValidationError('expected 1 key, got %s' % len(obj))
        tag = list(obj)[0]
        raw_val = obj[tag]
        if tag in data_type.definition._tagmap:
            val_data_type = data_type.definition._tagmap[tag]
            if isinstance(val_data_type, bv.Nullable) and raw_val is None:
                val = None
            elif isinstance(val_data_type, bv.Void):
                if raw_val is None or not strict:
                    # If raw_val is None, then this is the more verbose
                    # representation of a void union member. If raw_val isn't
                    # None, then maybe the spec has changed, so check if we're
                    # in strict mode.
                    val = None
                else:
                    raise bv.ValidationError('expected null, got %s' %
                                             bv.generic_type_name(raw_val))
            else:
                try:
                    val = _json_compat_obj_decode_helper(val_data_type,
                                                         raw_val,
                                                         strict,
                                                         old_style=True)
                except bv.ValidationError as e:
                    e.add_parent(tag)
                    raise
        else:
            if not strict and data_type.definition._catch_all:
                tag = data_type.definition._catch_all
            else:
                raise bv.ValidationError("unknown tag '%s'" % tag)
    else:
        raise bv.ValidationError("expected string or object, got %s" %
                                 bv.generic_type_name(obj))
    return data_type.definition(tag, val)
def _decode_union_old(data_type, obj, alias_validators, strict, for_msgpack):
    """
    The data_type argument must be a Union.
    See json_compat_obj_decode() for argument descriptions.
    """
    val = None
    if isinstance(obj, six.string_types):
        # Union member has no associated value
        tag = obj
        if tag in data_type.definition._tagmap:
            val_data_type = data_type.definition._tagmap[tag]
            if not isinstance(val_data_type, (bv.Void, bv.Nullable)):
                raise bv.ValidationError(
                    "expected object for '%s', got symbol" % tag)
        else:
            if not strict and data_type.definition._catch_all:
                tag = data_type.definition._catch_all
            else:
                raise bv.ValidationError("unknown tag '%s'" % tag)
    elif isinstance(obj, dict):
        # Union member has value
        if len(obj) != 1:
            raise bv.ValidationError('expected 1 key, got %s' % len(obj))
        tag = list(obj)[0]
        raw_val = obj[tag]
        if tag in data_type.definition._tagmap:
            val_data_type = data_type.definition._tagmap[tag]
            if isinstance(val_data_type, bv.Nullable) and raw_val is None:
                val = None
            elif isinstance(val_data_type, bv.Void):
                if raw_val is None or not strict:
                    # If raw_val is None, then this is the more verbose
                    # representation of a void union member. If raw_val isn't
                    # None, then maybe the spec has changed, so check if we're
                    # in strict mode.
                    val = None
                else:
                    raise bv.ValidationError('expected null, got %s' %
                                             bv.generic_type_name(raw_val))
            else:
                try:
                    val = _json_compat_obj_decode_helper(
                        val_data_type, raw_val, alias_validators, strict, True,
                        for_msgpack)
                except bv.ValidationError as e:
                    e.add_parent(tag)
                    raise
        else:
            if not strict and data_type.definition._catch_all:
                tag = data_type.definition._catch_all
            else:
                raise bv.ValidationError("unknown tag '%s'" % tag)
    else:
        raise bv.ValidationError("expected string or object, got %s" %
                                 bv.generic_type_name(obj))
    return data_type.definition(tag, val)
Esempio n. 4
0
def _determine_struct_tree_subtype(data_type, obj, strict):
    """
    Searches through the JSON-object-compatible dict using the data type
    definition to determine which of the enumerated subtypes `obj` is.
    """
    if '.tag' not in obj:
        raise bv.ValidationError("missing '.tag' key")
    if not isinstance(obj['.tag'], six.string_types):
        raise bv.ValidationError('expected string, got %s' %
                                 bv.generic_type_name(obj['.tag']),
                                 parent='.tag')

    # Find the subtype the tags refer to
    full_tags_tuple = (obj['.tag'],)
    if full_tags_tuple in data_type.definition._tag_to_subtype_:
        subtype = data_type.definition._tag_to_subtype_[full_tags_tuple]
        if isinstance(subtype, bv.StructTree):
            raise bv.ValidationError("tag '%s' refers to non-leaf subtype" %
                                     ('.'.join(full_tags_tuple)))
        return subtype
    else:
        if strict:
            # In strict mode, the entirety of the tag hierarchy should
            # point to a known subtype.
            raise bv.ValidationError("unknown subtype '%s'" %
                                     '.'.join(full_tags_tuple))
        else:
            # If subtype was not found, use the base.
            if data_type.definition._is_catch_all_:
                return data_type
            else:
                raise bv.ValidationError(
                    "unknown subtype '%s' and '%s' is not a catch-all" %
                    ('.'.join(full_tags_tuple), data_type.definition.__name__))
Esempio n. 5
0
def _decode_union(data_type, obj, alias_validators, strict, for_msgpack):
    """
    The data_type argument must be a Union.
    See json_compat_obj_decode() for argument descriptions.
    """
    val = None
    if isinstance(obj, six.string_types):
        # Handles the shorthand format where the union is serialized as only
        # the string of the tag.
        tag = obj
        if tag in data_type.definition._tagmap:
            val_data_type = data_type.definition._tagmap[tag]
            if not isinstance(val_data_type, (bv.Void, bv.Nullable)):
                raise bv.ValidationError(
                    "expected object for '%s', got symbol" % tag)
            if tag == data_type.definition._catch_all:
                raise bv.ValidationError(
                    "unexpected use of the catch-all tag '%s'" % tag)
        else:
            if not strict and data_type.definition._catch_all:
                tag = data_type.definition._catch_all
            else:
                raise bv.ValidationError("unknown tag '%s'" % tag)
    elif isinstance(obj, dict):
        tag, val = _decode_union_dict(
            data_type, obj, alias_validators, strict, for_msgpack)
    else:
        raise bv.ValidationError("expected string or object, got %s" %
                                 bv.generic_type_name(obj))
    return data_type.definition(tag, val)
def _determine_struct_tree_subtype(data_type, obj, strict):
	"""
	Searches through the JSON-object-compatible dict using the data type
	definition to determine which of the enumerated subtypes `obj` is.
	"""
	if '.tag' not in obj:
		raise bv.ValidationError("missing '.tag' key")
	if not isinstance(obj['.tag'], six.string_types):
		raise bv.ValidationError('expected string, got %s' %
								 bv.generic_type_name(obj['.tag']),
								 parent='.tag')

	# Find the subtype the tags refer to
	full_tags_tuple = (obj['.tag'],)
	if full_tags_tuple in data_type.definition._tag_to_subtype_:
		subtype = data_type.definition._tag_to_subtype_[full_tags_tuple]
		if isinstance(subtype, bv.StructTree):
			raise bv.ValidationError("tag '%s' refers to non-leaf subtype" %
									 ('.'.join(full_tags_tuple)))
		return subtype
	else:
		if strict:
			# In strict mode, the entirety of the tag hierarchy should
			# point to a known subtype.
			raise bv.ValidationError("unknown subtype '%s'" %
									 '.'.join(full_tags_tuple))
		else:
			# If subtype was not found, use the base.
			if data_type.definition._is_catch_all_:
				return data_type
			else:
				raise bv.ValidationError(
					"unknown subtype '%s' and '%s' is not a catch-all" %
					('.'.join(full_tags_tuple), data_type.definition.__name__))
def _decode_union(data_type, obj, strict):
	"""
	The data_type argument must be a Union.
	See json_compat_obj_decode() for argument descriptions.
	"""
	val = None
	if isinstance(obj, six.string_types):
		# Handles the shorthand format where the union is serialized as only
		# the string of the tag.
		tag = obj
		if tag in data_type.definition._tagmap:
			val_data_type = data_type.definition._tagmap[tag]
			if not isinstance(val_data_type, (bv.Void, bv.Nullable)):
				raise bv.ValidationError(
					"expected object for '%s', got symbol" % tag)
		else:
			if not strict and data_type.definition._catch_all:
				tag = data_type.definition._catch_all
			else:
				raise bv.ValidationError("unknown tag '%s'" % tag)
	elif isinstance(obj, dict):
		tag, val = _decode_union_dict(data_type, obj, strict)
	else:
		raise bv.ValidationError("expected string or object, got %s" %
								 bv.generic_type_name(obj))
	return data_type.definition(tag, val)
def _decode_list(data_type, obj, strict, old_style):
    """
    The data_type argument must be a List.
    See json_compat_obj_decode() for argument descriptions.
    """
    if not isinstance(obj, list):
        raise bv.ValidationError("expected list, got %s" % bv.generic_type_name(obj))
    return [_json_compat_obj_decode_helper(data_type.item_validator, item, strict, old_style) for item in obj]
def _decode_list(data_type, obj, strict, old_style):
    """
    The data_type argument must be a List.
    See json_compat_obj_decode() for argument descriptions.
    """
    if not isinstance(obj, list):
        raise bv.ValidationError(
            'expected list, got %s' % bv.generic_type_name(obj))
    return [_json_compat_obj_decode_helper(data_type.item_validator,
                                           item, strict, old_style)
            for item in obj]
def _decode_struct(data_type, obj, strict, old_style):
    """
    The data_type argument must be a Struct.
    See json_compat_obj_decode() for argument descriptions.
    """
    if not isinstance(obj, dict):
        raise bv.ValidationError("expected object, got %s" % bv.generic_type_name(obj))
    if strict:
        for key in obj:
            if key not in data_type.definition._all_field_names_ and not key.startswith(".tag"):
                raise bv.ValidationError("unknown field '%s'" % key)
    ins = data_type.definition()
    _decode_struct_fields(ins, data_type.definition._all_fields_, obj, strict, old_style)
    # Check that all required fields have been set.
    data_type.validate_fields_only(ins)
    return ins
def _decode_struct(data_type, obj, strict, old_style):
    """
    The data_type argument must be a Struct.
    See json_compat_obj_decode() for argument descriptions.
    """
    if not isinstance(obj, dict):
        raise bv.ValidationError('expected object, got %s' %
                                 bv.generic_type_name(obj))
    if strict:
        for key in obj:
            if (key not in data_type.definition._all_field_names_ and
                    not key.startswith('.tag')):
                raise bv.ValidationError("unknown field '%s'" % key)
    ins = data_type.definition()
    _decode_struct_fields(ins, data_type.definition._all_fields_, obj, strict,
                          old_style)
    # Check that all required fields have been set.
    data_type.validate_fields_only(ins)
    return ins
def _decode_struct(
        data_type, obj, alias_validators, strict, old_style, for_msgpack):
    """
    The data_type argument must be a Struct.
    See json_compat_obj_decode() for argument descriptions.
    """
    if obj is None and data_type.has_default():
        return data_type.get_default()
    elif not isinstance(obj, dict):
        raise bv.ValidationError('expected object, got %s' %
                                 bv.generic_type_name(obj))
    if strict:
        for key in obj:
            if (key not in data_type.definition._all_field_names_ and
                    not key.startswith('.tag')):
                raise bv.ValidationError("unknown field '%s'" % key)
    ins = data_type.definition()
    _decode_struct_fields(
        ins, data_type.definition._all_fields_, obj, alias_validators, strict,
        old_style, for_msgpack)
    # Check that all required fields have been set.
    data_type.validate_fields_only(ins)
    return ins
Esempio n. 13
0
def _decode_union_dict(data_type, obj, alias_validators, strict, for_msgpack):
    if '.tag' not in obj:
        raise bv.ValidationError("missing '.tag' key")
    tag = obj['.tag']
    if not isinstance(tag, six.string_types):
        raise bv.ValidationError(
            'tag must be string, got %s' % bv.generic_type_name(tag))

    if tag not in data_type.definition._tagmap:
        if not strict and data_type.definition._catch_all:
            return data_type.definition._catch_all, None
        else:
            raise bv.ValidationError("unknown tag '%s'" % tag)
    if tag == data_type.definition._catch_all:
        raise bv.ValidationError(
            "unexpected use of the catch-all tag '%s'" % tag)

    val_data_type = data_type.definition._tagmap[tag]
    if isinstance(val_data_type, bv.Nullable):
        val_data_type = val_data_type.validator
        nullable = True
    else:
        nullable = False

    if isinstance(val_data_type, bv.Void):
        if tag in obj:
            if obj[tag] is not None:
                raise bv.ValidationError('expected null, got %s' %
                                         bv.generic_type_name(obj[tag]))
        for key in obj:
            if key != tag and key != '.tag':
                raise bv.ValidationError("unexpected key '%s'" % key)
        val = None
    elif isinstance(val_data_type,
                    (bv.Primitive, bv.List, bv.StructTree, bv.Union)):
        if tag in obj:
            raw_val = obj[tag]
            try:
                val = _json_compat_obj_decode_helper(
                    val_data_type, raw_val, alias_validators, strict, False, for_msgpack)
            except bv.ValidationError as e:
                e.add_parent(tag)
                raise
        else:
            # Check no other keys
            if nullable:
                val = None
            else:
                raise bv.ValidationError("missing '%s' key" % tag)
        for key in obj:
            if key != tag and key != '.tag':
                raise bv.ValidationError("unexpected key '%s'" % key)
    elif isinstance(val_data_type, bv.Struct):
        if nullable and len(obj) == 1:  # only has a .tag key
            val = None
        else:
            # assume it's not null
            raw_val = obj
            try:
                val = _json_compat_obj_decode_helper(
                    val_data_type, raw_val, alias_validators, strict, False,
                    for_msgpack)
            except bv.ValidationError as e:
                e.add_parent(tag)
                raise
    else:
        assert False, type(val_data_type)
    return tag, val