Create a field which is immutable after being set

Question:

Is it possible to create a Pydantic field that does not have a default value and this value must be set on object instance creation and is immutable from then on?

e.g.

from pydantic import BaseModel

class User(BaseModel):
    user_id: int
    name: str

user = User(user_id=1, name='John')
user.user_id = 2 # raises immutable error
Asked By: KOB

||

Answers:

If you want to make all fields immutable, you can declare the class as being frozen

class User(BaseModel):
    user_id: int
    name: str
    class Config:
        frozen = True

However, this will make all fields immutable and not just a specific field

Answered By: Simon Hawe

You can try my solution below:

from pydantic import BaseModel, Field
class User(BaseModel):
    user_id: int
    name: str
    def setattr(cls, name, value):
        if name == "user_id": # or add more fiels here
            raise AttributeError("Cannot modify {}".format(name))
        else:
            return type.setattr(cls, name, value)

user = User(user_id=1, name='John')
user.user_id = 2 # raises immutable error
Answered By: Viettel Solutions

Pydantic already has the option you want. You can customize specific field by specifying allow_mutation to false. This raises a TypeError if the field is assigned on an instance.

from pydantic import BaseModel, Field


class User(BaseModel):
    user_id: int = Field(..., allow_mutation=False)
    name: str

    class Config:
        validate_assignment = True


user = User(user_id=1, name='John')
user.user_id = 2  # TypeError: "user_id" has allow_mutation set to False and cannot be assigned
Answered By: alex_noname
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.