|
55 | 55 | hybridmethod, |
56 | 56 | ) |
57 | 57 |
|
58 | | - |
59 | 58 | if TYPE_CHECKING: |
60 | 59 | from _typeshed import ( |
61 | 60 | SupportsRead, |
@@ -1522,6 +1521,12 @@ def to_dict( |
1522 | 1521 |
|
1523 | 1522 | @classmethod |
1524 | 1523 | def _from_dict_init(cls, mapping: Mapping[str, Any]) -> Mapping[str, Any]: |
| 1524 | + # Special case: google.protobuf.Struct has a single fields member but |
| 1525 | + # behaves like a transparent JSON object, so it needs to first be munged |
| 1526 | + # into `{fields: mapping}`. |
| 1527 | + if cls == Struct: |
| 1528 | + mapping = {"fields": mapping} |
| 1529 | + |
1525 | 1530 | init_kwargs: Dict[str, Any] = {} |
1526 | 1531 | for key, value in mapping.items(): |
1527 | 1532 | field_name = safe_snake_case(key) |
@@ -1552,7 +1557,7 @@ def _from_dict_init(cls, mapping: Mapping[str, Any]) -> Mapping[str, Any]: |
1552 | 1557 | if isinstance(value, list) |
1553 | 1558 | else sub_cls.from_dict(value) |
1554 | 1559 | ) |
1555 | | - elif meta.map_types and meta.map_types[1] == TYPE_MESSAGE: |
| 1560 | + elif meta.map_types and meta.map_types[1] == TYPE_MESSAGE and cls != Struct: |
1556 | 1561 | sub_cls = cls._betterproto.cls_by_field[f"{field_name}.value"] |
1557 | 1562 | value = {k: sub_cls.from_dict(v) for k, v in value.items()} |
1558 | 1563 | else: |
@@ -1582,6 +1587,7 @@ def _from_dict_init(cls, mapping: Mapping[str, Any]) -> Mapping[str, Any]: |
1582 | 1587 | ) |
1583 | 1588 |
|
1584 | 1589 | init_kwargs[field_name] = value |
| 1590 | + |
1585 | 1591 | return init_kwargs |
1586 | 1592 |
|
1587 | 1593 | @hybridmethod |
@@ -1926,6 +1932,7 @@ def which_one_of(message: Message, group_name: str) -> Tuple[str, Optional[Any]] |
1926 | 1932 | Int32Value, |
1927 | 1933 | Int64Value, |
1928 | 1934 | StringValue, |
| 1935 | + Struct, |
1929 | 1936 | Timestamp, |
1930 | 1937 | UInt32Value, |
1931 | 1938 | UInt64Value, |
|
0 commit comments