lidatong / dataclasses-json

Easily serialize Data Classes to and from JSON
MIT License
1.34k stars 150 forks source link

[BUG] Getting `UserWarning` for defining an attribute with type `dict[str, bytes] | None` #513

Open MartinXPN opened 5 months ago

MartinXPN commented 5 months ago

Description

I'm getting the following warning:

.../dataclasses_json/mm.py:288: UserWarning: Unknown type <class 'bytes'> at MyClass.attribute: dict[str, bytes] | None It's advised to pass the correct marshmallow type to `mm_field`.

Code snippet that reproduces the issue

import base64
from dataclasses import dataclass, field
from enum import Enum

from dataclasses_json import DataClassJsonMixin, LetterCase, Undefined, config

class DataClassJsonCamelMixIn(DataClassJsonMixin):
    dataclass_json_config = config(letter_case=LetterCase.CAMEL, undefined=Undefined.EXCLUDE)['dataclasses_json']

def base64_to_bytes(data: dict[str, str | bytes] | None) -> dict[str, bytes] | None:
    if data is not None and all(isinstance(content, str) for content in data.values()):
        return {filename: base64.b64decode(content.encode('utf-8')) for filename, content in data.items()}
    return data

def bytes_to_base64(data: dict[str, bytes] | None) -> dict[str, str] | None:
    if data is not None and all(isinstance(content, bytes) for content in data.values()):
        return {filename: base64.b64encode(content).decode('utf-8') for filename, content in data.items()}
    return data

@dataclass
class MyClass(DataClassJsonCamelMixIn):
    attribute: dict[str, bytes] | None = field(          # mapping filename -> binary content
        metadata=config(encoder=bytes_to_base64, decoder=base64_to_bytes),
        default=None,
    )

Describe the results you expected

I would expect the code to work without warnings.

Python version you are using

3.12

Environment description

boto3==1.33.6
botocore==1.33.6
certifi==2023.11.17
cffi==1.16.0
cfgv==3.4.0
charset-normalizer==3.3.2
coverage==7.3.2
cryptography==41.0.7
dataclasses-json==0.6.3
distlib==0.3.8
filelock==3.13.1
identify==2.5.33
idna==3.6
iniconfig==2.0.0
jmespath==1.0.1
marshmallow==3.20.1
mypy-extensions==1.0.0
nodeenv==1.8.0
numpy==1.26.2
packaging==23.2
pandas==2.1.3
platformdirs==4.1.0
pluggy==1.3.0
pre-commit==3.6.0
psutil==5.9.6
pycparser==2.21
pytest==7.4.3
pytest-cov==4.1.0
pytest-mock==3.12.0
python-dateutil==2.8.2
pytz==2023.3.post1
PyYAML==6.0.1
requests==2.31.0
s3transfer==0.8.2
setuptools==69.0.2
six==1.16.0
typing-inspect==0.9.0
typing_extensions==4.8.0
tzdata==2023.3
urllib3==2.0.7
virtualenv==20.25.0