[New-bugs-announce] [issue42742] Add abc.Mapping to dataclass

Anton Abrosimov report at bugs.python.org
Fri Dec 25 11:32:43 EST 2020

New submission from Anton Abrosimov <abrosimov.a.a at gmail.com>:

I want to add `abc.Mapping` extension to `dataclasses.dataclass`.


1. `asdict` makes a deep copy of the `dataclass` object. If I only want to iterate over the `field` attributes, I don't want to do a deep copy.
2. `dict(my_dataclass)` can be used as a `dict` representation of `my_dataclass` class without deep copying.
3. `myfunc(**my_dataclass)` looks better and is faster then `myfunc(**asdict(my_dataclass))`.
4. `len(my_dataclass) == len(asdict(my_dataclass))` is expected behavior.
5. `my_dataclass.my_field is my_dataclass['my_field']` is expected behavior.

Looks like a prototype:

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

@dataclass  # `(mapping=True)` creates such a class:
class MyDataclass(Mapping):
    a: int = 1
    b: int = 2

    # In `dataclasses._process_class`:
    # if `mapping` is `True`.
    # Make sure 'get', 'items', 'keys', 'values' is not in `MyDataclass` fields.

    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 field of the dataclass.")
        return getattr(self, f.name)

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

my_dataclass = MyDataclass(b=3)

{'a': 1, 'b': 3}
{'a': 1, 'b': 3}


Updating the `dataclasses.py`: `dataclass`, `_process_class`, `_DataclassParams`.
Set `mapping` argument to default `False`.

Can this enhancement be accepted?

components: Library (Lib)
messages: 383752
nosy: abrosimov.a.a
priority: normal
severity: normal
status: open
title: Add abc.Mapping to dataclass
type: enhancement
versions: Python 3.10

Python tracker <report at bugs.python.org>

More information about the New-bugs-announce mailing list