Author abrosimov.a.a
Recipients abrosimov.a.a, eric.smith
Date 2020-12-25.18:57:35
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1608922655.76.0.874479574566.issue42742@roundup.psfhosted.org>
In-reply-to
Content
Thanks for the answer, I agree.
The implementation should be like this?


from collections.abc import Mapping
from dataclasses import dataclass, fields, _FIELDS, _FIELD

class _DataclassMappingMixin(Mapping):
    def __iter__(self):
        return (f.name for f in fields(self))

    def __getitem__(self, key):
        fields = getattr(self, _FIELDS)
        f = fields[key]
        if f._field_type is not _FIELD:
            raise KeyError(f"'{key}' is not a dataclass field.")
        return getattr(self, f.name)

    def __len__(self):
        return len(fields(self))


def dataclass_mapping(cls=None, **kwargs):
    def apply_dataclass(cls):
        dataclass_wrap = dataclass(**kwargs)
        return dataclass_wrap(cls)

    def check_mapping_attrs(cls):
        mapping_attrs = (i for i in dir(_DataclassMappingMixin) if i[0] != '_')
        for key in mapping_attrs:
            if hasattr(cls, key):
                raise AttributeError(f"'{key}' is the Mapping reserved attribute.")

    def apply_mapping(cls):
        return type(cls.__name__ + 'Mapping',
                    (cls, _DataclassMappingMixin),
                    {})

    def wrap(cls):
        check_mapping_attrs(cls)
        cls_dataclass = apply_dataclass(cls)
        return apply_mapping(cls_dataclass)

    # See if we're being called as @dataclass or @dataclass().
    if cls is None:
        # We're called with parens.
        return wrap

    # We're called as @dataclass without parens.
    return wrap(cls)


@dataclass_mapping
class MyDataclass:
    a: int = 1
    b: int = 2


my_dataclass = MyDataclass(b='3')
print(my_dataclass.__class__.__name__)
print(my_dataclass['a'])
print(my_dataclass['b'])
print(dict(my_dataclass))
print(dict(**my_dataclass))
History
Date User Action Args
2020-12-25 18:57:35abrosimov.a.asetrecipients: + abrosimov.a.a, eric.smith
2020-12-25 18:57:35abrosimov.a.asetmessageid: <1608922655.76.0.874479574566.issue42742@roundup.psfhosted.org>
2020-12-25 18:57:35abrosimov.a.alinkissue42742 messages
2020-12-25 18:57:35abrosimov.a.acreate