Skip to content

Instantly share code, notes, and snippets.

@rednafi
Created March 18, 2022 20:32
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rednafi/82e34135e6b6b5b4d83d63876bc5a3b9 to your computer and use it in GitHub Desktop.
Save rednafi/82e34135e6b6b5b4d83d63876bc5a3b9 to your computer and use it in GitHub Desktop.
Mutate the fields of a dataclass by applying ad-hoc mutation callables.
from __future__ import annotations
import json
from collections.abc import Mapping
from dataclasses import dataclass
from typing import Callable
class Mutator:
def __init_subclass__(
cls, mutation: dict[str, Callable] | None = None
) -> None:
if not mutation:
return None
if not isinstance(mutation, Mapping):
raise TypeError(
"Mutation must be a Mapping between attribute name "
"and mutation callables.",
)
cls.__mutation__ = mutation
def __post_init__(self) -> None:
for attr, cb in self.__class__.__mutation__.items():
if not isinstance(attr, str):
raise TypeError(
f"Mutation attribute '{attr}' is not a string."
)
if not callable(cb):
raise TypeError(f"Mutation callable '{cb}' is not a callable.")
setattr(self, attr, cb(getattr(self, attr)))
@dataclass
class Hello(Mutator, mutation={"a": lambda x: x ** 2, "b": json.dumps}):
a: int
b: dict
print(Hello(4, {"a": "b"}))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment