I'm using pydantic with fastapi. And, I make Model like this.
# model.py
from multiprocessing import RLock
from pydantic import BaseModel
class ModelA(BaseModel):
file_1: str = 'test'
def __init__(self, **data: Any):
super().__init__(**data)
self._lock = RLock()
self._instance_variable: int = 1
@property
def lock(self):
return self._lock
@property
def instance_variable(self) -> int:
with self.lock:
return self._instance_variable
@instance_variable.setter
def instance_variable(self, v: int) -> int:
assert isinstance(v, int)
with self.lock:
self._instance_variable = v
And I make test like this
# test_model_a.py
def test_model_a():
instance = ModelA()
assert instance.json() == '{"field_1": "test"}'
After, I run the test, but the instance can't create with this error.
E ValueError: "ModelA" object has no field "_lock"
So, How can I pass this test...? Please... help me...
1 Answer 1
You need to use PrivateAttr field. And instead of a setter, use a workaround with __setattr__
from multiprocessing import RLock, synchronize
from typing import Any
from pydantic import BaseModel, PrivateAttr
class ModelA(BaseModel):
file_1: str = 'test'
_lock: synchronize.RLock = PrivateAttr()
_instance_variable: int = PrivateAttr()
def __init__(self, **data: Any):
super().__init__(**data)
self._lock = RLock()
self._instance_variable: int = 1
@property
def lock(self):
return self._lock
@property
def instance_variable(self) -> int:
with self.lock:
return self._instance_variable
def __setattr__(self, key, val):
if key == "instance_variable":
assert isinstance(val, int)
with self.lock:
self._instance_variable = val
return
super().__setattr__(key, val)
You can also avoid using a custom __init__
class ModelA(BaseModel):
file_1: str = 'test'
_lock: synchronize.RLock = PrivateAttr(default_factory=RLock)
_instance_variable: int = PrivateAttr(1)
# ...
answered Feb 25, 2021 at 10:01
alex_noname
33.3k7 gold badges95 silver badges110 bronze badges
Sign up to request clarification or add additional context in comments.
2 Comments
MR.LEE
umm... that's so good idea. but i want property.setter... isn't it possible...?
alex_noname
Apparently this is so github.com/samuelcolvin/pydantic/issues/1577
Explore related questions
See similar questions with these tags.
lang-py
BaseModel.dict()instead and compare 2 objects.