| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546 | from typing import Optional, Type, TypeVarfrom pydantic import BaseModel, ValidationErrorfrom .exceptions import BadRequestT = TypeVar("T", bound="ValueObject")class ValueObject(BaseModel):    class Config:        allow_mutation = False    def run_validation(self: T) -> T:        try:            return self.__class__(**self.dict())        except ValidationError as e:            raise BadRequest(e)    @classmethod    def create(cls: Type[T], **values) -> T:        try:            return cls(**values)        except ValidationError as e:            raise BadRequest(e)    def update(self: T, **values) -> T:        try:            return self.__class__(**{**self.dict(), **values})        except ValidationError as e:            raise BadRequest(e)    def __hash__(self):        return hash(self.__class__) + hash(tuple(self.__dict__.values()))K = TypeVar("K", bound="ValueObjectWithId")class ValueObjectWithId(ValueObject):    id: Optional[int] = None    def update(self: K, **values) -> K:        if "id" in values and self.id is not None and values["id"] != self.id:            raise ValueError("Cannot change the id")        return super().update(**values)
 |