コード例 #1
0
 def decode_union_old(self, data_type, obj):
     """
     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 data_type.definition._is_tag_present(tag, self.caller_permissions):
             val_data_type = data_type.definition._get_val_data_type(tag,
                                                                     self.caller_permissions)
             if not isinstance(val_data_type, (bv.Void, bv.Nullable)):
                 raise bv.ValidationError(
                     "expected object for '%s', got symbol" % tag)
         else:
             if not self.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 data_type.definition._is_tag_present(tag, self.caller_permissions):
             val_data_type = data_type.definition._get_val_data_type(tag,
                                                                     self.caller_permissions)
             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 self.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 = self.json_compat_obj_decode_helper(val_data_type, raw_val)
                 except bv.ValidationError as e:
                     e.add_parent(tag)
                     raise
         else:
             if not self.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)
コード例 #2
0
 def decode_union(self, data_type, obj):
     """
     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 data_type.definition._is_tag_present(tag,
                                                 self.caller_permissions):
             val_data_type = data_type.definition._get_val_data_type(
                 tag, self.caller_permissions)
             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)
         elif not self.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 = self.decode_union_dict(data_type, obj)
     else:
         raise bv.ValidationError("expected string or object, got %s" %
                                  bv.generic_type_name(obj))
     return data_type.definition(tag, val)
コード例 #3
0
    def decode_struct(self, data_type, obj):
        """
        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))
        all_fields = data_type.definition._all_fields_
        for extra_permission in self.caller_permissions.permissions:
            all_extra_fields = '_all_{}_fields_'.format(extra_permission)
            all_fields = all_fields + getattr(data_type.definition,
                                              all_extra_fields, [])

        if self.strict:
            all_field_names = data_type.definition._all_field_names_
            for extra_permission in self.caller_permissions.permissions:
                all_extra_field_names = '_all_{}_field_names_'.format(
                    extra_permission)
                all_field_names = all_field_names.union(
                    getattr(data_type.definition, all_extra_field_names, {}))

            for key in obj:
                if (key not in all_field_names and not key.startswith('.tag')):
                    raise bv.ValidationError("unknown field '%s'" % key)
        ins = data_type.definition()
        self.decode_struct_fields(ins, all_fields, obj)
        # Check that all required fields have been set.
        data_type.validate_fields_only_with_permissions(
            ins, self.caller_permissions)
        return ins
コード例 #4
0
    def determine_struct_tree_subtype(self, data_type, obj):
        """
        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 self.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__))
コード例 #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)
コード例 #6
0
 def decode_union(self, data_type, obj):
     """
     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 data_type.definition._is_tag_present(tag, self.caller_permissions):
             val_data_type = data_type.definition._get_val_data_type(
                 tag, self.caller_permissions)
             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)
         elif not self.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 = self.decode_union_dict(
             data_type, obj)
     else:
         raise bv.ValidationError("expected string or object, got %s" %
                                  bv.generic_type_name(obj))
     return data_type.definition(tag, val)
コード例 #7
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)
コード例 #8
0
    def decode_struct(self, data_type, obj):
        """
        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))
        all_fields = data_type.definition._all_fields_
        for extra_permission in self.caller_permissions.permissions:
            all_extra_fields = '_all_{}_fields_'.format(extra_permission)
            all_fields = all_fields + getattr(data_type.definition, all_extra_fields, [])

        if self.strict:
            all_field_names = data_type.definition._all_field_names_
            for extra_permission in self.caller_permissions.permissions:
                all_extra_field_names = '_all_{}_field_names_'.format(extra_permission)
                all_field_names = all_field_names.union(
                    getattr(data_type.definition, all_extra_field_names, {}))

            for key in obj:
                if (key not in all_field_names and
                        not key.startswith('.tag')):
                    raise bv.ValidationError("unknown field '%s'" % key)
        ins = data_type.definition()
        self.decode_struct_fields(ins, all_fields, obj)
        # Check that all required fields have been set.
        data_type.validate_fields_only_with_permissions(ins, self.caller_permissions)
        return ins
コード例 #9
0
    def determine_struct_tree_subtype(self, data_type, obj):
        """
        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 self.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__))
コード例 #10
0
 def decode_list(self, data_type, obj):
     """
     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 [
         self.json_compat_obj_decode_helper(data_type.item_validator, item)
         for item in obj]
コード例 #11
0
 def decode_list(self, data_type, obj):
     """
     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 [
         self.json_compat_obj_decode_helper(data_type.item_validator, item)
         for item in obj]
コード例 #12
0
 def decode_map(self, data_type, obj):
     """
     The data_type argument must be a Map.
     See json_compat_obj_decode() for argument descriptions.
     """
     if not isinstance(obj, dict):
         raise bv.ValidationError(
             'expected dict, got %s' % bv.generic_type_name(obj))
     return {
         self.json_compat_obj_decode_helper(data_type.key_validator, key):
         self.json_compat_obj_decode_helper(data_type.value_validator, value)
         for key, value in obj.items()
     }
コード例 #13
0
 def decode_map(self, data_type, obj):
     """
     The data_type argument must be a Map.
     See json_compat_obj_decode() for argument descriptions.
     """
     if not isinstance(obj, dict):
         raise bv.ValidationError(
             'expected dict, got %s' % bv.generic_type_name(obj))
     return {
         self.json_compat_obj_decode_helper(data_type.key_validator, key):
         self.json_compat_obj_decode_helper(data_type.value_validator, value)
         for key, value in obj.items()
     }
コード例 #14
0
def _decode_list(
        data_type, obj, alias_validators, strict, old_style, for_msgpack):
    """
    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, alias_validators, strict,
            old_style, for_msgpack)
        for item in obj]
コード例 #15
0
def _decode_list(
        data_type, obj, alias_validators, strict, old_style, for_msgpack):
    """
    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, alias_validators, strict,
            old_style, for_msgpack)
        for item in obj]
コード例 #16
0
def _decode_map(
        data_type, obj, alias_validators, strict, old_style, for_msgpack):
    """
    The data_type argument must be a Map.
    See json_compat_obj_decode() for argument descriptions.
    """
    if not isinstance(obj, dict):
        raise bv.ValidationError(
            'expected dict, got %s' % bv.generic_type_name(obj))

    result = {}
    for key, value in obj.items():
        result[_json_compat_obj_decode_helper(data_type.key_validator, key, alias_validators, strict,old_style, for_msgpack)] = _json_compat_obj_decode_helper(data_type.value_validator, value, alias_validators, strict,old_style, for_msgpack)

    return result
コード例 #17
0
def _decode_map(data_type, obj, alias_validators, strict, old_style,
                for_msgpack):
    """
    The data_type argument must be a Map.
    See json_compat_obj_decode() for argument descriptions.
    """
    if not isinstance(obj, dict):
        raise bv.ValidationError('expected dict, got %s' %
                                 bv.generic_type_name(obj))
    return {
        _json_compat_obj_decode_helper(data_type.key_validator, key,
                                       alias_validators, strict, old_style,
                                       for_msgpack):
        _json_compat_obj_decode_helper(data_type.value_validator, value,
                                       alias_validators, strict, old_style,
                                       for_msgpack)
        for key, value in obj.items()
    }
コード例 #18
0
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
コード例 #19
0
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
コード例 #20
0
    def decode_union_dict(self, data_type, obj):
        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 not data_type.definition._is_tag_present(tag,
                                                    self.caller_permissions):
            if not self.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._get_val_data_type(
            tag, self.caller_permissions)
        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 self.strict:
                # In strict mode, ensure there are no extraneous keys set. In
                # non-strict mode, we accept that other keys may be set due to a
                # change of the void type to another.
                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, bv.Map)):
            if tag in obj:
                raw_val = obj[tag]
                try:
                    val = self.json_compat_obj_decode_helper(
                        val_data_type, raw_val)
                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 = self.json_compat_obj_decode_helper(
                        val_data_type, raw_val)
                except bv.ValidationError as e:
                    e.add_parent(tag)
                    raise
        else:
            assert False, type(val_data_type)
        return tag, val
コード例 #21
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
コード例 #22
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
コード例 #23
0
    def decode_union_dict(self, data_type, obj):
        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 not data_type.definition._is_tag_present(tag, self.caller_permissions):
            if not self.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._get_val_data_type(tag, self.caller_permissions)
        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 self.strict:
                # In strict mode, ensure there are no extraneous keys set. In
                # non-strict mode, we accept that other keys may be set due to a
                # change of the void type to another.
                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, bv.Map)):
            if tag in obj:
                raw_val = obj[tag]
                try:
                    val = self.json_compat_obj_decode_helper(val_data_type, raw_val)
                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 = self.json_compat_obj_decode_helper(val_data_type, raw_val)
                except bv.ValidationError as e:
                    e.add_parent(tag)
                    raise
        else:
            assert False, type(val_data_type)
        return tag, val