Message383758
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)) |
|
Date |
User |
Action |
Args |
2020-12-25 18:57:35 | abrosimov.a.a | set | recipients:
+ abrosimov.a.a, eric.smith |
2020-12-25 18:57:35 | abrosimov.a.a | set | messageid: <1608922655.76.0.874479574566.issue42742@roundup.psfhosted.org> |
2020-12-25 18:57:35 | abrosimov.a.a | link | issue42742 messages |
2020-12-25 18:57:35 | abrosimov.a.a | create | |
|