Skip to content
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

Add ability to encode numpy datatypes #90

Closed
philipp-mohr opened this issue Jun 6, 2019 · 2 comments · Fixed by #470
Closed

Add ability to encode numpy datatypes #90

philipp-mohr opened this issue Jun 6, 2019 · 2 comments · Fixed by #470
Assignees
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@philipp-mohr
Copy link

philipp-mohr commented Jun 6, 2019

Hi,

in my program most of calculations are done with numpy and thus values are e.g of type np.int32 or numpy.ndarrays.

Consider following class:

@dataclass_json
@dataclass
class Results:
     value: int
     values: List[int]

results = Results()
results.value = some_numpy_computation_returning_numpy_int()
results.values = some_numpy_computation_returning_numpy_array()
json_data = results.to_json()

When running this code I would get a conversion error.

It would be very convenient if dataclassjson would be able to handle those errors, by passing in an extended json encoder which handles numpy datatypes.

In the dataclassjson code some cases are already dealt with the _ExtendedEncoder.

class _ExtendedEncoder(json.JSONEncoder):
    def default(self, o) -> JSON:
        result: JSON
        if _isinstance_safe(o, Collection):
            if _isinstance_safe(o, Mapping):
                result = dict(o)
            else:
                result = list(o)
        elif _isinstance_safe(o, datetime):
            result = o.timestamp()
        elif _isinstance_safe(o, UUID):
            result = str(o)
        elif _isinstance_safe(o, Enum):
            result = o.value
        else:
            result = json.JSONEncoder.default(self, o)
        return result

However, I cannot extend this decoder to support my needs, since cls=_ExtendedEncoder is not in the argument list of to_json.

 class DataClassJsonMixin(abc.ABC):
    """
    DataClassJsonMixin is an ABC that functions as a Mixin.

    As with other ABCs, it should not be instantiated directly.
    """

    def to_json(self,
                *,
                skipkeys: bool = False,
                ensure_ascii: bool = True,
                check_circular: bool = True,
                allow_nan: bool = True,
                indent: Optional[Union[int, str]] = None,
                separators: Tuple[str, str] = None,
                default: Callable = None,
                sort_keys: bool = False,
                **kw) -> str:
        return json.dumps(_asdict(self),
                          cls=_ExtendedEncoder,
                          skipkeys=skipkeys,
                          ensure_ascii=ensure_ascii,
                          check_circular=check_circular,
                          allow_nan=allow_nan,
                          indent=indent,
                          separators=separators,
                          default=default,
                          sort_keys=sort_keys,
                          **kw)

Would it be possible to change it to:

 class DataClassJsonMixin(abc.ABC):
    """
    DataClassJsonMixin is an ABC that functions as a Mixin.

    As with other ABCs, it should not be instantiated directly.
    """

    def to_json(self,
                *,
                skipkeys: bool = False,
                ensure_ascii: bool = True,
                check_circular: bool = True,
                allow_nan: bool = True,
                indent: Optional[Union[int, str]] = None,
                separators: Tuple[str, str] = None,
                default: Callable = None,
                sort_keys: bool = False,
                cls: json.JSONEncoder=_ExtendedEncoder,
                **kw) -> str:
        return json.dumps(_asdict(self),
                          cls=cls,
                          skipkeys=skipkeys,
                          ensure_ascii=ensure_ascii,
                          check_circular=check_circular,
                          allow_nan=allow_nan,
                          indent=indent,
                          separators=separators,
                          default=default,
                          sort_keys=sort_keys,
                          **kw)

I know about the possibility to define an encoder via metadata, but instead of adding this to all of my fields of the dataclasses, I'd rather prefer a global solution.

@lidatong lidatong added enhancement New feature or request help wanted Extra attention is needed labels Jun 22, 2019
@scottj97
Copy link

scottj97 commented Jul 2, 2019

I second this request. I'm looking for a way to use my custom data types which can provide their own to/from JSON serialization in the class. It doesn't look like there's any way to do this today without adding the encoder/decoder metadata to every field of these types.

@scottj97
Copy link

scottj97 commented Sep 8, 2023

#470 does not fix this issue. That PR only explains how to use field metadata to specify the encoding, something OP was already aware of:

I know about the possibility to define an encoder via metadata, but instead of adding this to all of my fields of the dataclasses, I'd rather prefer a global solution.

This issue should not have been closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
4 participants