lovasoa / marshmallow_dataclass

Automatic generation of marshmallow schemas from dataclasses.

Home Page:https://lovasoa.github.io/marshmallow_dataclass/html/marshmallow_dataclass.html

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

list[enum] ignores "by_value": True flag

rayrapetyan opened this issue · comments

Sample code:

from dataclasses import field
from enum import StrEnum
from typing import (
    ClassVar,
    List,
    Type,
)

from marshmallow import Schema
from marshmallow_dataclass import dataclass


class Color(StrEnum):
    RED = "red"
    GREEN = "green"
    BLUE = "blue"


@dataclass
class Thing:
    color: Color = field(metadata={"by_value": True})
    color_list: List[Color] = field(default_factory=list, metadata={"by_value": True})
    Schema: ClassVar[Type[Schema]] = Schema  # pylint: disable=invalid-name


thing = Thing(color=Color.RED, color_list=[Color.RED, Color.GREEN, Color.BLUE])  # Example data
serialized_thing = Thing.Schema().dump(thing)
print(serialized_thing)

Actual result:

{'color': 'red', 'color_list': ['RED', 'GREEN', 'BLUE']}

Expected result:

{'color': 'red', 'color_list': ['red', 'green', 'blue]}

Does this work:

from dataclasses import field
from enum import StrEnum
from typing import ClassVar, List, Type

from marshmallow_dataclass import dataclass

class Color(StrEnum):
    RED = "red"
    GREEN = "green"
    BLUE = "blue"

from marshmallow import Schema, fields

@dataclass
class Thing:
    color: Color = field(metadata={"by_value": True})
    color_list: List[Color] = field(
        default_factory=list, metadata=dict(cls_or_instance=fields.Enum(Color, by_value=True))
    )
    # Schema: ClassVar[Type["Schema"]] = Schema  # pylint: disable=invalid-name

thing = Thing(color=Color.RED, color_list=[Color.RED, Color.GREEN, Color.BLUE])  # Example data
serialized_thing = Thing.Schema().dump(thing)
print(serialized_thing)

You have to change this line https://github.com/lovasoa/marshmallow_dataclass/blob/master/marshmallow_dataclass/__init__.py#L654 to

            return list_type(**metadata)

You need a way to set the metadata for the cls_or_instance attribute. Maybe it can do a `cls_or_instance_metadata = metadata.pop("cls_or_instance_metadata") inside so you can provide as:

    color_list: List[Color] = field(
        default_factory=list, metadata=dict(cls_or_instance_metadata=dict(enum=Color, by_value=True))
    )