14    __slots__ = (
"_annotation",)
 
   16    def __init__(self, annotation: typing.Type):
 
   18        Initialize the field information. 
   21            annotation: The type annotation of the field. 
   26    def annotation(self) -> typing.Type[typing.Any] | None:
 
   28        Get the type annotation of the field. 
   35        Check if the field is required for the schema. 
   41    if isinstance(value, collections.abc.Mapping):
 
   43    elif isinstance(value, collections.abc.Sequence) 
and not isinstance(value, str):
 
   46            return collections.Sequence[Any]
 
   49            element_type = type(element)
 
   51            original = typing.get_origin(element_type)
 
   53                original = element_type
 
   54            if original 
is typing.Mapping 
or isinstance(original, type) 
and issubclass(original,
 
   55                                                                                       collections.abc.Mapping):
 
 
   58                element_types.add(element_type)
 
 
   59        if len(element_types) == 1:
 
   60            return collections.abc.Sequence[next(iter(element_types))]
 
   61        union_type = typing.Union[tuple(element_types)]
 
   62        return collections.abc.Sequence[union_type]
 
   69    Recursively infer a schema from a mapping. 
   71    Types that are specially handled: 
   72        - collections.abc.Mapping: converted to a schema. Keys are converted to field names and corresponding value types are converted to field types. 
   73        - collections.abc.Sequence with heterogeneous elements: all different element types are included in a union type. 
   75    Other types are directly inferred from the type of the value with no special handling. 
   78    for key, value 
in mapping.items():
 
   79        assert isinstance(key, str), f
"Key must be a string, got {key} of type {type(key)}" 
   80        assert key.isidentifier(), f
"Key must be a valid identifier, got {key}" 
   82        field_infos[key] = 
FieldInfo(inferred_type)
 
   84    _class.from_json = classmethod(
lambda cls, json_str: json.loads(json_str))