lidatong / dataclasses-json

Easily serialize Data Classes to and from JSON

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

API features / improvements

lidatong opened this issue · comments

Creating this parent issue to track API improvements / upgrades

  1. Support forward references (which will enable recursive dataclasses): #5
  2. Full typing support: #23
  3. coerce_keys kwarg for encoding: #29
  4. user-supplied overrides #42
  5. Sharing encoder / decoder in wider scopes (currently must be per-field. type, class, global are all potential scopes) #139

What's the ETA for fixing this?

Is there anything we can do as a workaround to make mypy pass?

commented

Is there anything we can do as a workaround to make mypy pass?

Besides # type: ignore?

@lidatong It is possible to have to_json include computed properties (@property)? I'm using the package for a json repr, not purely for serialization/deserialization.

@gshpychka, you can try the following:

  1. Define the DataClassJsonMixin-nested class A
  2. Define class B which is not dataclass on its own
  3. In class B, define the required property

Code Example

from dataclasses_json import *
from dataclasses import *

@dataclass
class ClassA(DataClassJsonMixin):
    field_1: str
    field_2: int = field(init=False, repr=True, default=0)


class ClassB(ClassA):
    @property
    def field_2(self) -> int:
        return len(self.field_1)


def main():
    a = ClassA('1234')
    b = ClassB('456')
    
    print(a.to_json())
    print(b.to_json())
    
    return 0

if (__name__ == '__main__'):
    exit_code = main()
    exit(exit_code)

Execution Result

{"field_1": "1234", "field_2": 0}
{"field_1": "456", "field_2": 3}

@gshpychka, @USSX-Hares, my solution:

import dataclasses

import dataclasses_json


@dataclasses.dataclass
# the solution will only work when using inheritance
class SomeClass(dataclasses_json.DataClassJsonMixin):
    field_1: str

    @property
    def field_2(self) -> int:
        return len(self.field_1)

    # override the method in order to add computable properties to JSON
    def to_dict(
        self,
        encode_json: bool = False,
    ) -> dict[str, dataclasses_json.core.Json]:
        # first call the parent method to get non-computable properties
        data = super().to_dict(encode_json=encode_json)

        # then manually set computable properties
        data["field_2"] = self.field_2

        return data


if __name__ == "__main__":
    instance = SomeClass("12345")
    print(instance.to_json())

Output:

{"field_1": "12345", "field_2": 5}