@@ -94,6 +94,12 @@ def _dig_fields(__opt: Any, *names: str) -> Any:
9494 return __opt
9595
9696
97+ def _field_type (__field : dataclasses .Field [Any ]) -> type [Any ]:
98+ field_type = __field .type
99+ assert isinstance (field_type , type )
100+ return field_type
101+
102+
97103def _process_union (target : type [Any ]) -> Any :
98104 """
99105 Filters None out of Unions. If a Union only has one item, return that item.
@@ -158,7 +164,9 @@ def _nested_dataclass_to_names(__target: type[Any], *inner: str) -> Iterator[lis
158164
159165 if dataclasses .is_dataclass (__target ):
160166 for field in dataclasses .fields (__target ):
161- yield from _nested_dataclass_to_names (field .type , * inner , field .name )
167+ yield from _nested_dataclass_to_names (
168+ _field_type (field ), * inner , field .name
169+ )
162170 else :
163171 yield list (inner )
164172
@@ -321,7 +329,7 @@ def _unrecognized_dict(
321329 yield "." .join ((* above , keystr ))
322330 continue
323331 (inner_option_field ,) = matches
324- inner_option = inner_option_field . type
332+ inner_option = _field_type ( inner_option_field )
325333 if dataclasses .is_dataclass (inner_option ):
326334 yield from _unrecognized_dict (
327335 settings [keystr ], inner_option , (* above , keystr )
@@ -490,12 +498,12 @@ def convert(cls, item: Any, target: type[Any]) -> object:
490498 """
491499 target , annotations = _process_annotated (target )
492500 raw_target = _get_target_raw_type (target )
493- if dataclasses .is_dataclass (raw_target ):
501+ if isinstance ( raw_target , type ) and dataclasses .is_dataclass (raw_target ):
494502 fields = dataclasses .fields (raw_target )
495503 values = ((k .replace ("-" , "_" ), v ) for k , v in item .items ())
496504 return raw_target (
497505 ** {
498- k : cls .convert (v , * [f . type for f in fields if f .name == k ])
506+ k : cls .convert (v , * [_field_type ( f ) for f in fields if f .name == k ])
499507 for k , v in values
500508 }
501509 )
@@ -579,24 +587,25 @@ def convert_target(self, target: type[T], *prefixes: str) -> T:
579587 errors = []
580588 prep : dict [str , Any ] = {}
581589 for field in dataclasses .fields (target ): # type: ignore[arg-type]
582- if dataclasses .is_dataclass (field .type ):
590+ field_type = _field_type (field )
591+ if dataclasses .is_dataclass (field_type ):
583592 try :
584593 prep [field .name ] = self .convert_target (
585- field . type , * prefixes , field .name
594+ field_type , * prefixes , field .name
586595 )
587596 except Exception as e :
588597 name = "." .join ([* self .prefixes , * prefixes , field .name ])
589598 e .__notes__ = [* getattr (e , "__notes__" , []), f"Field: { name } " ] # type: ignore[attr-defined]
590599 errors .append (e )
591600 continue
592601
593- is_dict = _get_target_raw_type (field . type ) is dict
602+ is_dict = _get_target_raw_type (field_type ) is dict
594603
595604 for source in self .sources :
596605 if source .has_item (* prefixes , field .name , is_dict = is_dict ):
597606 simple = source .get_item (* prefixes , field .name , is_dict = is_dict )
598607 try :
599- tmp = source .convert (simple , field . type )
608+ tmp = source .convert (simple , field_type )
600609 except Exception as e :
601610 name = "." .join ([* self .prefixes , * prefixes , field .name ])
602611 e .__notes__ = [* getattr (e , "__notes__" , []), f"Field { name } " ] # type: ignore[attr-defined]
0 commit comments