@@ -450,7 +450,6 @@ def parse_fields(value: bytes) -> Generator[ParsedField, None, None]:
450
450
451
451
class ProtoClassMetadata :
452
452
__slots__ = (
453
- "oneof_group_by_field" ,
454
453
"oneof_field_by_group" ,
455
454
"default_gen" ,
456
455
"cls_by_field" ,
@@ -459,7 +458,6 @@ class ProtoClassMetadata:
459
458
"sorted_field_names" ,
460
459
)
461
460
462
- oneof_group_by_field : dict [str , str ] # TODO delete (still used in the rust codec for now)
463
461
oneof_field_by_group : dict [str , set [dataclasses .Field ]]
464
462
field_name_by_number : dict [int , str ]
465
463
meta_by_field_name : dict [str , FieldMetadata ]
@@ -468,7 +466,6 @@ class ProtoClassMetadata:
468
466
cls_by_field : dict [str , type ]
469
467
470
468
def __init__ (self , cls : type [Message ]):
471
- by_field = {}
472
469
by_group : dict [str , set ] = {}
473
470
by_field_name = {}
474
471
by_field_number = {}
@@ -479,15 +476,11 @@ def __init__(self, cls: type[Message]):
479
476
meta = FieldMetadata .get (field )
480
477
481
478
if meta .group :
482
- # This is part of a one-of group.
483
- by_field [field .name ] = meta .group
484
-
485
479
by_group .setdefault (meta .group , set ()).add (field )
486
480
487
481
by_field_name [field .name ] = meta
488
482
by_field_number [meta .number ] = field .name
489
483
490
- self .oneof_group_by_field = by_field
491
484
self .oneof_field_by_group = by_group
492
485
self .field_name_by_number = by_field_number
493
486
self .meta_by_field_name = by_field_name
@@ -588,15 +581,15 @@ def _value_to_dict(
588
581
return value , not bool (value )
589
582
590
583
591
- def _value_from_dict (value : Any , proto_type : str , field_type : type , unwrap : Callable [[], type ] | None = None ) -> Any :
584
+ def _value_from_dict (value : Any , meta : FieldMetadata , field_type : type ) -> Any :
592
585
# TODO directly pass `meta` when available for maps
593
586
594
- if proto_type == TYPE_MESSAGE :
595
- msg_cls = unwrap () if unwrap else field_type
587
+ if meta . proto_type == TYPE_MESSAGE :
588
+ msg_cls = meta . unwrap () if meta . unwrap else field_type
596
589
597
590
msg = msg_cls .from_dict (value )
598
591
599
- if unwrap :
592
+ if meta . unwrap :
600
593
return msg .to_wrapped ()
601
594
return msg
602
595
@@ -1056,7 +1049,7 @@ def to_dict(
1056
1049
return output
1057
1050
1058
1051
@classmethod
1059
- def _from_dict_init (cls , mapping : Mapping [str , Any ]) -> Mapping [str , Any ]:
1052
+ def _from_dict_init (cls , mapping : Mapping [str , Any ] | Any ) -> Mapping [str , Any ]:
1060
1053
# TODO restructure using other function
1061
1054
init_kwargs : dict [str , Any ] = {}
1062
1055
for key , value in mapping .items ():
@@ -1070,14 +1063,9 @@ def _from_dict_init(cls, mapping: Mapping[str, Any]) -> Mapping[str, Any]:
1070
1063
1071
1064
if meta .proto_type == TYPE_MESSAGE :
1072
1065
if meta .repeated :
1073
- value = [
1074
- _value_from_dict (item , meta .proto_type , cls ._betterproto .cls_by_field [field_name ], meta .unwrap )
1075
- for item in value
1076
- ]
1066
+ value = [_value_from_dict (item , meta , cls ._betterproto .cls_by_field [field_name ]) for item in value ]
1077
1067
else :
1078
- value = _value_from_dict (
1079
- value , meta .proto_type , cls ._betterproto .cls_by_field [field_name ], meta .unwrap
1080
- )
1068
+ value = _value_from_dict (value , meta , cls ._betterproto .cls_by_field [field_name ])
1081
1069
1082
1070
elif meta .map_meta and meta .map_meta [1 ].proto_type == TYPE_MESSAGE :
1083
1071
sub_cls = cls ._betterproto .cls_by_field [f"{ field_name } .value" ]
@@ -1100,7 +1088,7 @@ def _from_dict_init(cls, mapping: Mapping[str, Any]) -> Mapping[str, Any]:
1100
1088
return init_kwargs
1101
1089
1102
1090
@hybridmethod
1103
- def from_dict (cls : type [Self ], value : Mapping [str , Any ]) -> Self : # type: ignore
1091
+ def from_dict (cls : type [Self ], value : Mapping [str , Any ] | Any ) -> Self : # type: ignore
1104
1092
"""
1105
1093
Parse the key/value pairs into the a new message instance.
1106
1094
@@ -1114,10 +1102,13 @@ def from_dict(cls: type[Self], value: Mapping[str, Any]) -> Self: # type: ignor
1114
1102
:class:`Message`
1115
1103
The initialized message.
1116
1104
"""
1105
+ if not isinstance (value , Mapping ) and hasattr (cls , "from_wrapped" ): # type: ignore
1106
+ return cls .from_wrapped (value ) # type: ignore
1107
+
1117
1108
return cls (** cls ._from_dict_init (value ))
1118
1109
1119
1110
@from_dict .instancemethod
1120
- def from_dict (self , value : Mapping [str , Any ]) -> Self :
1111
+ def from_dict (self , value : Mapping [str , Any ] | Any ) -> Self :
1121
1112
"""
1122
1113
Parse the key/value pairs into the current message instance. This returns the
1123
1114
instance itself and is therefore assignable and chainable.
@@ -1194,49 +1185,6 @@ def from_json(self: T, value: str | bytes) -> T:
1194
1185
"""
1195
1186
return self .from_dict (json .loads (value ))
1196
1187
1197
- def from_pydict (self : T , value : Mapping [str , Any ]) -> T :
1198
- """
1199
- Parse the key/value pairs into the current message instance. This returns the
1200
- instance itself and is therefore assignable and chainable.
1201
-
1202
- Parameters
1203
- -----------
1204
- value: Dict[:class:`str`, Any]
1205
- The dictionary to parse from.
1206
-
1207
- Returns
1208
- --------
1209
- :class:`Message`
1210
- The initialized message.
1211
- """
1212
- for key in value :
1213
- field_name = safe_snake_case (key )
1214
- meta = self ._betterproto .meta_by_field_name .get (field_name )
1215
- if not meta :
1216
- continue
1217
-
1218
- if value [key ] is not None :
1219
- if meta .proto_type == TYPE_MESSAGE :
1220
- v = getattr (self , field_name )
1221
- cls = self ._betterproto .cls_by_field [field_name ]
1222
- if issubclass (cls , list ):
1223
- raise NotImplementedError # TODO look at this
1224
- elif meta .unwrap :
1225
- v = value [key ]
1226
- else :
1227
- v = cls ().from_pydict (value [key ])
1228
- elif meta .map_meta and meta .map_meta [1 ].proto_type == TYPE_MESSAGE :
1229
- v = getattr (self , field_name )
1230
- cls = self ._betterproto .cls_by_field [f"{ field_name } .value" ]
1231
- for k in value [key ]:
1232
- v [k ] = cls ().from_pydict (value [key ][k ])
1233
- else :
1234
- v = value [key ]
1235
-
1236
- if v is not None :
1237
- setattr (self , field_name , v )
1238
- return self
1239
-
1240
1188
def is_set (self , name : str ) -> bool :
1241
1189
"""
1242
1190
Check if field with the given name has been set.
0 commit comments