dataclasses-json icon indicating copy to clipboard operation
dataclasses-json copied to clipboard

API features / improvements

Open lidatong opened this issue 6 years ago • 6 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

lidatong avatar Nov 04 '18 17:11 lidatong

What's the ETA for fixing this?

baco avatar Mar 22 '20 22:03 baco

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

Trolldemorted avatar Oct 23 '21 18:10 Trolldemorted

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

Besides # type: ignore?

huyz avatar Dec 01 '21 12:12 huyz

@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 avatar May 17 '22 11:05 gshpychka

@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}

USSX-Hares avatar Jun 10 '22 07:06 USSX-Hares

@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}

thewizardplusplus avatar Oct 27 '22 03:10 thewizardplusplus