-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Description
Output of python -c "import pydantic.utils; print(pydantic.utils.version_info())":
pydantic version: 1.5.1
pydantic compiled: True
install path: ...snip...
python version: 3.6.9 (default, Jun 26 2020, 13:24:16) [GCC 4.2.1 Compatible Apple LLVM 11.0.0 (clang-1100.0.33.16)]
platform: Darwin-18.7.0-x86_64-i386-64bit
optional deps. installed: ['typing-extensions']
I'm seeing what appears to be inconsistent behavior with each_item=True when I'm using a field that's a list of tuples.
For instance, a 'normal' model illustrates what seems to be logical behavior.
from typing import List, Tuple
from pydantic import BaseModel, validator
class Thing(BaseModel):
things: List[str]
@validator("things", each_item=False)
def validate_all_things(cls, val):
print(f"all vals: {val}")
return val
@validator("things", each_item=True)
def validate_single_thing(cls, val):
print(f"single val: {val}")
return val
>>> Thing(things=["one", "two", "three,four"])
single val: one
single val: two
single val: three,four
all vals: ['one', 'two', 'three,four']
Thing(things=['one', 'two', 'three,four'])But if the field is anything like List[Tuple[str], str]], then behavior is absolutely different.
class Thing2(BaseModel):
things: List[Tuple[str, str]]
@validator("things", each_item=False)
def validate_all_things(cls, val):
print(f"all vals: {val}")
return val
@validator("things", each_item=True)
def validate_single_thing(cls, val):
print(f"single val: {val}")
return val
>>> Thing2(things=[("one", "two"), ("three", "four")])
single val: one
single val: two
single val: three
single val: four
all vals: [('one', 'two'), ('three', 'four')]
Thing2(things=[('one', 'two'), ('three', 'four')])The output from validate_all_things makes perfect sense - it's just the entire list passed in.
I would expect, however, that each_item would do just what it implies, namely calling the validator on each item of the list no matter what the item is. Instead, it's operating on every value within each tuple within the list, and I cannot get it to perform in a way where val == ("one", "two").
Is this expected behavior? If so, why?
I mean, strings are iterable just like tuples, so why isn't each_item iterating over the characters of each string in the first case?