Example #1
0
    def clean(self, value):
        """Cleans an input value for an AMQP composite type field."""
        # If the field is mandatory, `value` may not be None or NOT_PROVIDED
        if value in (None, NOT_PROVIDED):
            if self.mandatory:
                raise ValidationError("required", self, value)

            # If the field is not mandatory, bail out early with a basetypes.Null
            # instance.
            return Null()

        # If the field specified its type name as "*", `value` is assumed to be
        # either a tuple of (type name, value) or a Provider which satisfied
        # the requirements of the field.
        if self.type_name == "*":
            if not isinstance(value, Provider):
                # Restricted types are provided as (type_name, value)
                assert len(value) == 2
                type_name, value = value
                meta = get_by_type_name(type_name)
                value = meta.create(value) if not self.multiple else self.clean_multiple(meta, value)

            self.clean_provider(value)
        else:
            meta = get_by_type_name(self.type_name)

        # If the field allows multiple values, the input value must be an a list
        # or an Array holding the members. Note that at this point, polymorphic
        # field types have already been casted to a Provider instance, for which
        # validation has already been done.
        if self.multiple and self.type_name != "*":
            members = value
            assert isinstance(value, list)

            # Array instances must be monomorphic, polymorphic collecions
            # are a validation error.
            if len(set(map(type, members))) > 1:
                raise ValidationError("polymorphic", self, members)

            value = Array.create("array", [meta.create(x) for x in members])

        elif not isinstance(value, Encodable):
            value = meta.create(value)

        # At this point, value MUST be an Encodable.
        assert isinstance(value, Encodable)
        return value
Example #2
0
 def create(self, *args):
     """Create an instance of the AMQP type specified by
     :attr:`type_name`.
     """
     meta = get_by_type_name(self.type_name)
     if meta.is_restricted():
         # Restricted types are always scalar, so the first
         # argument is the desired input value.
         args = args[0] if args else None
         if not args:
             args = [None]
     instance = meta.create(*args)
     self._run_validators(instance)
     return instance
Example #3
0
    def create(self, value):
        """Create a new instance of the defined AMQP type. Return an
        :class:`.Encodable` instance representing the cleaned and validated
        input.
        """
        value = self.clean(value)

        if self.type_class == 'primitive':
            # If the Meta represents a primitive type, simple clean and validate
            # and return the appropriate Encodable implementation.
            return basetypes.encodable_factory(self.type_name, value)

        elif self.type_class == 'restricted':
            source =  get_by_type_name(self.source)
            return Restricted.frommeta(self, source.create(value))
        else:
            assert self.type_class == 'composite'
            return Composite.frommeta(self, value)
Example #4
0
def encodable(type_name, value):
    """Create a new :class:`.Composite` or :class:`.Restricted` instance."""
    meta = registry.get_by_type_name(type_name)
    return meta.create(value)