Search code examples
pythonpython-3.6pydantic

How to make pydantic class fields immutable?


I am trying to create a pydantic class with Immutable class fields (not instance fields).

Here is my base code:

from pydantic import BaseModel

class ImmutableModel(BaseModel):
    _name: str = "My Name"
    _age: int = 25

ImmutableModel._age = 26

print("Class variables:")
print(f"Name: {ImmutableModel._name}")
print(f"Age: {ImmutableModel._age}")

Output:

Class variables:
Name: My Name
Age: 26

I tried using the Config class inside my ImmutableModel to make fields immutable. But it seems like it only works for instance class fields.

class Config:
    allow_mutation = False

FYI, I use Python 3.6.13 and pydantic==1.9.2


Solution

  • Initially, I tried to achieve creating immutable Class and Instance using pydantic module.

    Now I were able to manage it using native method itself. Since this was completely defined by me and immutable, its fine to have no validation.

    class ImmutableMetaclass(type):
        
        def __setattr__(cls, name, value):
            raise AttributeError("Cannot create or set class attribute '{}'".format(name))
    
    class MyImmutableClass(metaclass=ImmutableMetaclass):
        
        # Define all allowed class attributes here
        CONSTANT_1 = 1
    
        def __setattr__(self, name, value):
            raise AttributeError("Cannot create or set class or instance attribute '{}'".format(name))
    
    immutable_class = MyImmutableClass
    immutable_class.CONSTANT_1 = 100
    immutable_class.CONSTANT_2 = 200
    
    immutable_instance = MyImmutableClass()
    immutable_instance.CONSTANT_1 = 100
    immutable_instance.CONSTANT_3 = 300
    

    All the above code raises AttributeError.