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)
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()
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()
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)