scrapbook icon indicating copy to clipboard operation
scrapbook copied to clipboard

scrap.Scrap as a dataclass

Open philippefutureboy opened this issue 4 years ago • 0 comments
trafficstars

Hey there!

While I was fiddling around with scrapbook, I ended up writing a dataclass for scrap.Scrap items. I noticed in the source that you have a comment that says:

# dataclasses would be nice here...
Scrap = namedtuple("Scrap", ["name", "data", "encoder", "display"])
Scrap.__new__.__defaults__ = (None,)

So I figured you could be interested by the implementation I made! :) See below:

@dataclass
class Scrap(collections.abc.Mapping):
    name: str
    data: Any
    encoder: str
    display: str = None

    def keys(self):
        return self.__dataclass_fields__.keys() # pylint: disable=no-member

    def __getitem__(self, key: str) -> Any:
        if isinstance(key, str):
            if not hasattr(self, key):
                raise KeyError(key)
            return getattr(self, key)
        else:
            raise TypeError(f"Unsupported key type: {type(key)}")

    def __len__(self):
        return len(self.__dataclass_fields__.keys()) # pylint: disable=no-member

    def __iter__(self):
        return (attr for attr in dataclasses.astuple(self))

    def asdict(self) -> dict:
        return dataclasses.asdict(self)

    def astuple(self) -> tuple:
        return dataclasses.astuple(self)
  • keys, __getitem__, __len__ are for the Mapping protocol, to allow the Scrap to be converted to a dict using the ** operator ({**scrap})
  • __iter__ is to support unpacking the scrap
  • asdict, astuple are for convenience

philippefutureboy avatar Aug 19 '21 19:08 philippefutureboy