Question: I am trying to add custom steps to the Pydantic model __init__ method. Pseudo Sample Code : class Model(BaseModel): a: int b: Optional[List[int]] = None c: Optional[int] = None def __init__(self, *args, **kwargs): super.__init__(*args, **kwargs) self.method() def method(self): assert self.a is not None, "Value for a is not set" # As a safety precaution let's say self.c = sum(self.b) # Adds all the values in B and sets the sum to C  When I initialise the method [In]: x = Model(a=1, b=[1, 2, 3, 4]) [Out]: pydantic.error_wrappers.ValidationError: 1 validation error for A response -> Model -> 0 Value for a is not set (type=value_error)  I get this error even thou I have set both a and b in the model. Can someone help me out The same problem works if the method is called outside the __init__ method, but I want the method to be called upon initialisation and not manually Pseudo Sample Code : class Model(BaseModel): a: int b: Optional[List[int]] = None c: Optional[int] = None def method(self): assert self.a is not None, "Value for a is not set" # As a safety precaution let's say self.c = sum(self.b) # Adds all the values in B and sets the sum to C  When I initialise the method [In]: x = Model(a=1, b=[1, 2, 3, 4]) [Out]: Model(a=1, b=[1, 2 , 3 , 4], c=None) [In]: x.method() [Out]: Model(a=1, b=[1, 2 , 3 , 4], c=10)   Note: I'm restricted with the pydantic version '1.10.14'and cannot upgrade it for several reasons.   Update Jun 18th After getting a few answers and help, I went with the validator method. But I went through few hiccups, which I have explained below Updated pseudo code : from pydantic import validator class Model(BaseModel): a: int b: Optional[List[int]] = None c: Optional[int] = None @root_validator(pre=False, allow_reuse=False) def method(cls, values, **kwargs): assert values["b"] is not None, "Value for b is not set" values["c"] = sum(values["b"]) return values def serialise(self): ... // Creates protobuf message @classmethod def deserialize(cls, message) -> "Model": ... // reads the protobuf message and creates the cls return cls( a = message.a c = message.c ) >>> x = Model(a=1, b=[1, 2, 3, 4])) Model(a=1 b=[1, 2, 3, 4] c=10) >>> >>> x.serialise() xxxxxxxxxxxxxxxxxxxxx >>> >>> y = Model.desirealise("xxxxxxxxxxxxxxxxxxxxx") Value for b is not set  In this case, I don't want to run the validator when c is manually set during the model is initiated. Hence, I set skip_on_failure flag to True for the validator and I have made the below changes to prevent the check from failing. from pydantic import validator class Model(BaseModel): a: int b: Optional[List[int]] = None c: Optional[int] = None @root_validator(pre=False, allow_reuse=False) def method(cls, values, **kwargs): if values["c"] is not None: return values assert values["b"] is not None, "Value for b is not set" values["c"] sum(values["b"]) return values def serialise(self): ... // Creates protobuf message @classmethod def deserialize(cls, message) -> "Model": ... // reads the protobuf message and creates the cls return cls( a = message.a c = message.c ) >>> x = Model(a=1, b=[1, 2, 3, 4])) Model(a=1 b=[1, 2, 3, 4] c=10) >>> >>> x.serialise() xxxxxxxxxxxxxxxxxxxxx >>> >>> y = Model.desirealise("xxxxxxxxxxxxxxxxxxxxx") Model(a=1, b=None, c=10)  This code resolves my issues and works properly with the system, but I want to know if this is a best practice or If any other way is there to do this.

Answer: Pydantic v2 answer: If you want to both validate and add logic to your property during initialization, you can use model_validator: from pydantic import BaseModel from pydantic import model_validator class Model(BaseModel): a: int b: Optional[List[int]] = None c: Optional[int] = None @model_validator(mode='after') def method(self): assert self.a is not None, "Value for a is not set" # As a safety precausion let say self.c = sum(self.b) # Adds all the value in B and sets the sum to C print(Model(a=1, b=[1, 2, 3, 4])) # a=1 b=[1, 2, 3, 4] c=10  But I think it's a better approach to separate responsabilities with @model_validator and @computed_field: from pydantic import computed_field from pydantic import model_validator class Model(BaseModel): a: int b: Optional[List[int]] = None @model_validator(mode='after') def method(self): assert self.a is not None, "Value for a is not set" @computed_field @property def c(self) -> int: return sum(self.b) print(Model(a=1, b=[1, 2, 3, 4])) # a=1 b=[1, 2, 3, 4] c=10  Pydantic v1 (1.10.14) answer: Since pydantic v1 don't offer computed_field, you can still rely on model/field validations. In this case, the validator decorator: from pydantic import validator class Model(BaseModel): a: int b: Optional[List[int]] = None c: Optional[int] = None @validator("c", always=True) def method(cls, v, values, **kwargs): assert values["a"] is not None, "Value for a is not set" return sum(values["b"]) print(Model(a=1, b=[1, 2, 3, 4])) # a=1 b=[1, 2, 3, 4] c=10