What is the distinction between implicitly setting an optional attribute to None with typing.Optional[] versus explicitly assigning typing.Optional[] = None when creating Pydantic models? In both cases, the attribute will eventually have a value of None when the class object is instantiated.
import typing
import pydantic
class Bar(pydantic.BaseModel):
a: typing.Optional[int]
@pydantic.validator('a', always=True, pre=True)
def check_a(cls, v, values, field):
print("WITHOUT NONE")
print(values)
print(field)
return v
class Baz(pydantic.BaseModel):
a: typing.Optional[int] = None
@pydantic.validator('a', always=True, pre=True)
def check_a(cls, v, values, field):
print("WITH NONE")
print(values)
print(field)
return v
print(Bar())
print(Baz())
Output:
WITHOUT NONE
{}
name='a' type=Optional[int] required=False default=None
a=None
WITH NONE
{}
name='a' type=Optional[int] required=False default=None
a=None
Whilst the previous answer is correct for pydantic v1, note that pydantic v2, released 2023-06-30, changed this behavior.
As specified in the migration guide:
Pydantic V2 changes some of the logic for specifying whether a field annotated as Optional is required (i.e., has no default value) or not (i.e., has a default value of None or any other value of the corresponding type), and now more closely matches the behavior of dataclasses. Similarly, fields annotated as Any no longer have a default value of None.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With