| 123456789101112131415161718192021222324252627282930313233343536373839404142 | # (c) Nelen & Schuurmansfrom datetime import datetimefrom datetime import timezonefrom typing import Optionalfrom typing import Typefrom typing import TypeVarfrom .exceptions import BadRequestfrom .value_object import ValueObject__all__ = ["RootEntity", "now"]def now():    # this function is there so that we can mock it in tests    return datetime.now(timezone.utc)T = TypeVar("T", bound="RootEntity")class RootEntity(ValueObject):    id: Optional[int] = None    created_at: datetime    updated_at: datetime    @classmethod    def create(cls: Type[T], **values) -> T:        values.setdefault("created_at", now())        values.setdefault("updated_at", values["created_at"])        return super(RootEntity, cls).create(**values)    def update(self: T, **values) -> T:        if "id" in values and self.id is not None and values["id"] != self.id:            raise BadRequest("Cannot change the id of an entity")        values.setdefault("updated_at", now())        return super().update(**values)    def __hash__(self):        assert self.id is not None        return hash(self.__class__) + hash(self.id)
 |