check ModelField().validate_always when inheriting (#1545)

fix #1155

* fix issure #1155

* add changes.1545-dcHHH.md

* improve change description

Co-authored-by: dchhh <hudacong@geetest.com>
Co-authored-by: Samuel Colvin <samcolvin@gmail.com>
This commit is contained in:
ll H
2020-06-29 18:04:44 +08:00
committed by GitHub
parent e5fff9ccd0
commit 8aebba2c35
3 changed files with 24 additions and 4 deletions
+1
View File
@@ -0,0 +1 @@
Move the assignment of `field.validate_always` in `fields.py` so the `always` parameter of validators work on inheritance.
+4 -4
View File
@@ -365,10 +365,6 @@ class ModelField(Representation):
# user will need to call model.update_forward_refs()
return
self.validate_always = getattr(self.type_, 'validate_always', False) or any(
v.always for v in self.class_validators.values()
)
if self.required is False and default_value is None:
self.allow_none = True
@@ -511,6 +507,10 @@ class ModelField(Representation):
and class validators. This method should be idempotent, e.g. it should be safe to call multiple times
without mis-configuring the field.
"""
self.validate_always = getattr(self.type_, 'validate_always', False) or any(
v.always for v in self.class_validators.values()
)
class_validators_ = self.class_validators.values()
if not self.sub_fields or self.shape == SHAPE_GENERIC:
get_validators = getattr(self.type_, '__get_validators__', None)
+19
View File
@@ -287,6 +287,25 @@ def test_validate_always():
assert check_calls == 2
def test_validate_always_on_inheritance():
check_calls = 0
class ParentModel(BaseModel):
a: str = None
class Model(ParentModel):
@validator('a', pre=True, always=True)
def check_a(cls, v):
nonlocal check_calls
check_calls += 1
return v or 'xxx'
assert Model().a == 'xxx'
assert check_calls == 1
assert Model(a='y').a == 'y'
assert check_calls == 2
def test_validate_not_always():
check_calls = 0