-
-
Notifications
You must be signed in to change notification settings - Fork 47
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Possible to serialize a top-level list/array? #69
Comments
It's not possible with mashumaro at the moment. I'm thinking about a separated from dataclass function for serialization but it's not coming soon. |
|
At the moment, it can be done using a generic dataclass wrapper. A couple of examples: @dataclass
class CommonClass(
Generic[T],
DataClassJSONMixin,
DataClassMessagePackMixin,
DataClassYAMLMixin,
DataClassTOMLMixin,
):
x: T
@classmethod
def __pre_deserialize__(cls: Type[T], d: Dict[Any, Any]) -> Dict[Any, Any]:
return {"x": d}
def __post_serialize__(self: T, d: Dict[Any, Any]) -> Dict[Any, Any]:
return d["x"]
def create_unpacker(data_type: T, fmt: Literal["dict", "json"] = "dict"):
class ConcreteClass(CommonClass[data_type]):
pass
if fmt == "json":
def unpacker(data) -> T:
return ConcreteClass.from_json(data)
else:
def unpacker(data) -> T:
return ConcreteClass.from_dict(data)
return unpacker
def create_packer(data_type: T, fmt: Literal["dict", "json"] = "dict"):
class ConcreteClass(CommonClass[data_type]):
pass
if fmt == "json":
def packer(data) -> T:
return ConcreteClass(data).to_json()
else:
def packer(data) -> T:
return ConcreteClass(data).to_dict()
return packer
@dataclass
class MyDataClass(DataClassDictMixin):
x: datetime
my_json_packer = create_packer(list[MyDataClass], fmt="json")
print(repr(my_json_packer([MyDataClass(datetime.utcnow())])))
# '[{"x": "2023-03-26T10:33:44.567742"}]'
my_dict_packer = create_packer(list[MyDataClass], fmt="dict")
print(repr(my_dict_packer([MyDataClass(datetime.utcnow())])))
# [{'x': '2023-03-26T10:34:06.932352'}]
def from_json(cls: T, data) -> T:
class ConcreteClass(CommonClass[cls]):
pass
return ConcreteClass.from_json(data).x
def as_json(cls: T, obj) -> T:
class ConcreteClass(CommonClass[cls]):
pass
return ConcreteClass(obj).to_json()
print(repr(as_json(list[MyDataClass], [MyDataClass(datetime.utcnow())])))
# '[{"x": "2023-03-26T10:38:24.234213"}]'
print(from_json(list[MyDataClass], '[{"x": "2023-03-26T10:36:25.902384"}]'))
# [MyDataClass(x=datetime.datetime(2023, 3, 26, 10, 36, 25, 902384))] |
Is that specific construct something you were going to add to the package? Is there anything I can do to help bring this feature to fruition? |
I've given a couple of examples of how this issue can be addressed from outside, but I wasn't going to include it to the package because it's still a workaround. For native support I see the following steps:
You can play around with |
Started working with One suggestion is to add the functionality above into the package, even if it's not a complete solution and then modify it later, with the risk of breaking the API if a better solution comes along. This is much needed 😃 |
Good news everyone! I’m working on it, so this functionality will be a part of 3.11 release. |
The long-awaited pull request has landed! See updated docs here. |
JSON allows an array at top level (instead of an object). It would be nice if we have eg a List[MyDataClass] to be able to serialize this directly without a wrapper. Is this possible in mashumaro?
Currently I'm working around this like follows:
The text was updated successfully, but these errors were encountered: