def field_factory(
    name: str,
    native_type: typing.Any,
    default: typing.Any = dataclasses.MISSING,
    default_factory: typing.Any = dataclasses.MISSING,
    metadata: typing.Dict = dataclasses.MISSING,
) -> FieldType:
    if native_type in PYTHON_INMUTABLE_TYPES:
        klass = INMUTABLE_FIELDS_CLASSES[native_type]
        return klass(name=name,
                     type=native_type,
                     default=default,
                     metadata=metadata)
    elif utils.is_self_referenced(native_type):
        return SelfReferenceField(name=name,
                                  type=native_type,
                                  default=default,
                                  metadata=metadata)
    elif native_type is types.Fixed:
        return FixedField(name=name,
                          type=native_type,
                          default=default,
                          metadata=metadata)
    elif isinstance(native_type, typing._GenericAlias):
        origin = native_type.__origin__

        if origin not in (
                tuple,
                list,
                dict,
                typing.Union,
                collections.abc.Sequence,
                collections.abc.MutableSequence,
                collections.abc.Mapping,
                collections.abc.MutableMapping,
        ):
            raise ValueError(f"""
                Invalid Type for field {name}. Accepted types are list, tuple, dict or typing.Union
                """)

        klass = CONTAINER_FIELDS_CLASSES[origin]
        return klass(
            name=name,
            type=native_type,
            default=default,
            default_factory=default_factory,
            metadata=metadata,
        )
    elif native_type in PYTHON_LOGICAL_TYPES:
        klass = LOGICAL_TYPES_FIELDS_CLASSES[native_type]
        return klass(name=name,
                     type=native_type,
                     default=default,
                     metadata=metadata)
    else:
        return RecordField(name=name,
                           type=native_type,
                           default=default,
                           metadata=metadata)
Beispiel #2
0
    def generate_values_type(self):
        """
        Process typing.Dict. Avro assumes that the key of a map is always a string,
        so we take the second argument to determine the value type
        """
        values_type = self.type.__args__[1]

        if values_type in PRIMITIVE_AND_LOGICAL_TYPES:
            klass = PRIMITIVE_LOGICAL_TYPES_FIELDS_CLASSES[values_type]
            self.values_type = klass.avro_type
        elif utils.is_self_referenced(values_type):
            # Checking for a self reference. Maybe is a typing.ForwardRef
            self.values_type = self._get_self_reference_type(values_type)
        else:
            self.values_type = values_type.avro_schema_to_python()
Beispiel #3
0
    def generate_items_type(self):
        # because avro can have only one type, we take the first one
        items_type = self.type.__args__[0]

        if items_type in PRIMITIVE_AND_LOGICAL_TYPES:
            klass = PRIMITIVE_LOGICAL_TYPES_FIELDS_CLASSES[items_type]
            self.items_type = klass.avro_type
        elif utils.is_self_referenced(items_type):
            # Checking for a self reference. Maybe is a typing.ForwardRef
            self.items_type = self._get_self_reference_type(items_type)
        elif utils.is_union(items_type):
            self.items_type = UnionField.generate_union(
                items_type.__args__,
                default=self.default,
                default_factory=self.default_factory,
            )
        else:
            # Is Avro Record Type
            self.items_type = items_type.avro_schema_to_python()
Beispiel #4
0
def field_factory(
    name: str,
    native_type: typing.Any,
    default: typing.Any = dataclasses.MISSING,
    default_factory: typing.Any = dataclasses.MISSING,
    metadata: typing.Mapping = dataclasses.field(default_factory=dict),
) -> FieldType:
    if native_type in PYTHON_INMUTABLE_TYPES:
        klass = INMUTABLE_FIELDS_CLASSES[native_type]
        return klass(name=name,
                     type=native_type,
                     default=default,
                     metadata=metadata)
    elif utils.is_self_referenced(native_type):
        return SelfReferenceField(name=name,
                                  type=native_type,
                                  default=default,
                                  metadata=metadata)
    elif native_type is types.Fixed:
        return FixedField(name=name,
                          type=native_type,
                          default=default,
                          metadata=metadata)
    elif native_type is types.Enum:
        return EnumField(name=name,
                         type=native_type,
                         default=default,
                         metadata=metadata)
    elif isinstance(native_type, typing._GenericAlias):  # type: ignore
        origin = native_type.__origin__

        if origin not in (
                tuple,
                list,
                dict,
                typing.Union,
                collections.abc.Sequence,
                collections.abc.MutableSequence,
                collections.abc.Mapping,
                collections.abc.MutableMapping,
        ):
            raise ValueError(f"""
                Invalid Type for field {name}. Accepted types are list, tuple, dict or typing.Union
                """)

        container_klass = CONTAINER_FIELDS_CLASSES[origin]
        return container_klass(  # type: ignore
            name=name,
            type=native_type,
            default=default,
            metadata=metadata,
            default_factory=default_factory,
        )
    elif native_type in PYTHON_LOGICAL_TYPES:
        klass = LOGICAL_TYPES_FIELDS_CLASSES[native_type]  # type: ignore
        return klass(name=name,
                     type=native_type,
                     default=default,
                     metadata=metadata)
    elif inspect.isclass(native_type) and issubclass(
            native_type, schema_generator.AvroModel):
        return RecordField(name=name,
                           type=native_type,
                           default=default,
                           metadata=metadata)
    else:
        msg = (
            f"Type {native_type} is unknown. Please check the valid types at "
            "https://marcosschroh.github.io/dataclasses-avroschema/fields_specification/#avro-field-and-python-types-summary"  # noqa: E501
        )

        raise ValueError(msg)