diff --git a/karapace/avro_dataclasses/introspect.py b/karapace/avro_dataclasses/introspect.py index 01f07d4a5..93f3ab9ce 100644 --- a/karapace/avro_dataclasses/introspect.py +++ b/karapace/avro_dataclasses/introspect.py @@ -5,7 +5,7 @@ from __future__ import annotations -from .schema import AvroType, FieldSchema, RecordSchema +from .schema import AvroType, EnumType, FieldSchema, MapType, RecordSchema from collections.abc import Mapping from dataclasses import Field, fields, is_dataclass, MISSING from enum import Enum @@ -98,10 +98,10 @@ def _field_type(field: Field, type_: object) -> AvroType: # pylint: disable=too # Handle enums. if isinstance(type_, type) and issubclass(type_, Enum): - return FieldSchema( + return EnumType( { # Conditionally set a default. - **({"default": field.default.value} if field.default is not MISSING else {}), # type: ignore[misc] + **({"default": field.default.value} if field.default is not MISSING else {}), "name": type_.__name__, "type": "enum", "symbols": [value.value for value in type_], @@ -115,15 +115,11 @@ def _field_type(field: Field, type_: object) -> AvroType: # pylint: disable=too raise UnderspecifiedAnnotation("Key and value types must be specified for map types") if args[0] is not str: raise UnsupportedAnnotation("Key type must be str") - return FieldSchema( + return MapType( { "type": "map", "values": _field_type(field, args[1]), - **( - {"default": field.default_factory()} - if field.default_factory is not MISSING - else {} # type: ignore[misc] - ), + **({"default": field.default_factory()} if field.default_factory is not MISSING else {}), } ) @@ -134,12 +130,16 @@ def _field_type(field: Field, type_: object) -> AvroType: # pylint: disable=too ) -T = TypeVar("T") +T = TypeVar("T", str, int, bool, Enum, None) -def transform_default(type_: type[T], default: T) -> object: - if isinstance(type_, type) and issubclass(type_, Enum): - return default.value # type: ignore[attr-defined] +def transform_default(type_: type[T], default: T) -> str | int | bool | None: + if isinstance(default, Enum): + assert isinstance(type_, type) + assert issubclass(type_, Enum) + assert isinstance(default.value, (str, int, bool)) or default.value is None + return default.value + assert not (isinstance(type_, type) and issubclass(type_, Enum)) return default @@ -150,7 +150,7 @@ def field_schema(field: Field) -> FieldSchema: } return ( { - **schema, # type: ignore[misc] + **schema, "default": transform_default(field.type, field.default), } if field.default is not MISSING diff --git a/requirements/requirements-typing.txt b/requirements/requirements-typing.txt index d8579f1b8..a8f75adfa 100644 --- a/requirements/requirements-typing.txt +++ b/requirements/requirements-typing.txt @@ -8,7 +8,7 @@ certifi==2023.7.22 # via # -c requirements-dev.txt # sentry-sdk -mypy==1.4.1 +mypy==1.6.1 # via -r requirements-typing.in mypy-extensions==1.0.0 # via mypy