I have a Pydantic DTO that looks like this:
from pydantic import AfterValidator, model_validator, BaseModel
class Bid(BaseModel):
start_block: Annotated[DateTime, AfterValidator(block_validator)]
end_block: Annotated[DateTime, AfterValidator(block_validator)]
threshold: int
pq_pairs: Annotated[List[PriceQuantityPair], AfterValidator(pq_pair_validator)] = Field(min_length=1)
@model_validator(mode="after")
def validate_bid(self) -> Self:
"""Validate an offer."""
# Check that the start block is before the end block
if self.start_block >= self.end_block:
raise ValueError("The start block must be before the end block.")
for pq_pair in self.pq_pairs:
if self.threshold > pq_pair.quantity:
raise ValueError("The threshold must be less than or equal to the quantity.")
# Return the object now that we've validated it
return self
This works fine but Pylint is raising a linting error:
E1133: Non-iterable value self.pq_pairs is used in an iterating context (not-an-iterable)
I would assume that this has something to do with the use of Annotated
but I'm not sure what to do about it. Any help would be appreciated.
It took a while, but after some experimenting I figured it out! Defining pq_pairs
in the following way fixes the problem:
class Bid(BaseModel):
pq_pairs: Annotated[List[PriceQuantityPair], AfterValidator(pq_pair_validator), Field(min_length=1)]
Assume that assigning Field
to the attribute confusing pylint.