Skip to content

Commit

Permalink
check ModelField().validate_always when inheriting (pydantic#1545)
Browse files Browse the repository at this point in the history
fix pydantic#1155

* fix issure pydantic#1155

* add changes.1545-dcHHH.md

* improve change description

Co-authored-by: dchhh <hudacong@geetest.com>
Co-authored-by: Samuel Colvin <samcolvin@gmail.com>
  • Loading branch information
3 people committed Jun 29, 2020
1 parent e5fff9c commit 8aebba2
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 4 deletions.
1 change: 1 addition & 0 deletions changes/1545-dcHHH.md
@@ -0,0 +1 @@
Move the assignment of `field.validate_always` in `fields.py` so the `always` parameter of validators work on inheritance.
8 changes: 4 additions & 4 deletions pydantic/fields.py
Expand Up @@ -365,10 +365,6 @@ def prepare(self) -> None:
# 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

Expand Down Expand Up @@ -511,6 +507,10 @@ def populate_validators(self) -> None:
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)
Expand Down
19 changes: 19 additions & 0 deletions tests/test_validators.py
Expand Up @@ -287,6 +287,25 @@ def check_a(cls, v):
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

Expand Down

0 comments on commit 8aebba2

Please sign in to comment.