|
16 | 16 | from beartype.door import is_bearable
|
17 | 17 | from beartype.roar import BeartypeCallHintParamViolation
|
18 | 18 | from dataclasses import dataclass, is_dataclass
|
19 |
| -from typing import overload, TypeVar, Generic, Any, Optional, Union, Literal |
| 19 | +from typing import overload, TypeVar, Generic, Any, Optional, Union, Literal, Iterator |
20 | 20 | from typing_extensions import dataclass_transform
|
21 | 21 |
|
22 | 22 | from .compat import (
|
@@ -985,11 +985,31 @@ def literal(self, arg: DeField[Any]) -> str:
|
985 | 985 | )
|
986 | 986 |
|
987 | 987 | def default(self, arg: DeField[Any], code: str) -> str:
|
988 |
| - if arg.alias: |
989 |
| - aliases = (f'"{s}"' for s in [arg.name, *arg.alias]) |
990 |
| - exists = f'_exists_by_aliases({arg.datavar}, [{",".join(aliases)}])' |
| 988 | + """ |
| 989 | + Renders supplying default value during deserialization. |
| 990 | + """ |
| 991 | + |
| 992 | + def get_aliased_fields(arg: Field[Any]) -> Iterator[str]: |
| 993 | + return (f'"{s}"' for s in [arg.name, *arg.alias]) |
| 994 | + |
| 995 | + if arg.flatten: |
| 996 | + # When a field has the `flatten` attribute, iterate over its dataclass fields. |
| 997 | + # This ensures that the code checks keys in the data while considering aliases. |
| 998 | + flattened = [] |
| 999 | + for subarg in defields(arg.type): |
| 1000 | + if subarg.alias: |
| 1001 | + aliases = get_aliased_fields(subarg) |
| 1002 | + flattened.append(f'_exists_by_aliases({arg.datavar}, [{",".join(aliases)}])') |
| 1003 | + else: |
| 1004 | + flattened.append(f'"{subarg.name}" in {arg.datavar}') |
| 1005 | + exists = " and ".join(flattened) |
991 | 1006 | else:
|
992 |
| - exists = f'"{arg.conv_name()}" in {arg.datavar}' |
| 1007 | + if arg.alias: |
| 1008 | + aliases = get_aliased_fields(arg) |
| 1009 | + exists = f'_exists_by_aliases({arg.datavar}, [{",".join(aliases)}])' |
| 1010 | + else: |
| 1011 | + exists = f'"{arg.conv_name()}" in {arg.datavar}' |
| 1012 | + |
993 | 1013 | if has_default(arg):
|
994 | 1014 | return f'({code}) if {exists} else serde_scope.defaults["{arg.name}"]'
|
995 | 1015 | elif has_default_factory(arg):
|
|
0 commit comments