Hello,
I configured the following field:
representative_email: EmailStr = None
When passing an empty string "" as value, I get the following error:
Email address is not valid (error_type=ValueError track=EmailStr)
How can I configure va validator to support those values a I can't change the incoming format?
You should be able to use a validator function and return none instead of an empty string.
On mobile so I can't give a more complete answer, but feel free to ask again if you're still not sure.
Hello,
I tried it with the following code but it doesn't seem to work:
from pydantic import BaseModel, validator, EmailStr
class Demo(BaseModel):
e: EmailStr: None
@validator('e', pre=True, always=False)
def validate_e(cls, val):
if val == "":
return None
return val
Demo()
Demo(e=None)
Demo(e="")
The traceback is the following one:
Traceback (most recent call last):
File "test.py", line 14, in <module>
Demo(e="")
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/pydantic/main.py", line 153, in __init__
self.__setstate__(self._process_values(data))
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/pydantic/main.py", line 297, in _process_values
raise ValidationError(errors)
pydantic.exceptions.ValidationError: error validating input
e:
expected string or bytes-like object (error_type=TypeError track=EmailStr)
In case the validator alway parameter is set to True, the traceback is:
Traceback (most recent call last):
File "test.py", line 12, in <module>
Demo()
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/pydantic/main.py", line 153, in __init__
self.__setstate__(self._process_values(data))
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/pydantic/main.py", line 297, in _process_values
raise ValidationError(errors)
pydantic.exceptions.ValidationError: error validating input
e:
expected string or bytes-like object (error_type=TypeError track=EmailStr)
What am I doing wrong?
Maybe you need Optional[EmailStr]
For anyone curious on a working solution here:
class EmailEmptyAllowedStr(EmailStr):
@classmethod
def validate(cls, value: str) -> str:
if value == "":
return value
return super().validate(value)
I've also made this generic solution for using with ints, Literal or other types as well:
PydanticField = TypeVar("PydanticField")
class EmptyStrToNone(Generic[PydanticField]):
@classmethod
def __get_validators__(cls):
yield cls.validate
@classmethod
def validate(cls, v: PydanticField, field: ModelField) -> Optional[PydanticField]:
if v == "":
return None
return v
Then you can use as:
LiteralExample = Literal["A", "B"]
class Example(BaseModel):
literal_example: Optional[EmptyStrToNone[LiteralExample]]
int_example: Optional[EmptyStrToNone[int]]
Most helpful comment
For anyone curious on a working solution here: