Standard Library Types
Pydantic supports many common types from the Python standard library. If you need stricter processing see
Strict Types, including if you need to constrain the values allowed (e.g. to require a positive int).
Booleans¶
A standard bool field will raise a ValidationError if the value is not one of the following:
- A valid boolean (i.e.
TrueorFalse), - The integers
0or1, - a
strwhich when converted to lower case is one of'0', 'off', 'f', 'false', 'n', 'no', '1', 'on', 't', 'true', 'y', 'yes' - a
byteswhich is valid per the previous rule when decoded tostr
Note
If you want stricter boolean logic (e.g. a field which only permits True and False) you can
use StrictBool.
Here is a script demonstrating some of these behaviors:
from pydantic import BaseModel, ValidationError
class BooleanModel(BaseModel):
bool_value: bool
print(BooleanModel(bool_value=False))
#> bool_value=False
print(BooleanModel(bool_value='False'))
#> bool_value=False
print(BooleanModel(bool_value=1))
#> bool_value=True
try:
BooleanModel(bool_value=[])
except ValidationError as e:
print(str(e))
"""
1 validation error for BooleanModel
bool_value
Input should be a valid boolean [type=bool_type, input_value=[], input_type=list]
"""
Datetime Types¶
Pydantic supports the following datetime types:
datetime.datetime¶
-
datetimefields will accept values of type:datetime; an existingdatetimeobjectintorfloat; assumed as Unix time, i.e. seconds (if >=-2e10and <=2e10) or milliseconds (if <-2e10or >2e10) since 1 January 1970str; the following formats are accepted:YYYY-MM-DD[T]HH:MM[:SS[.ffffff]][Z or [±]HH[:]MM]YYYY-MM-DDis accepted in lax mode, but not in strict modeintorfloatas a string (assumed as Unix time)
datetime.dateinstances are accepted in lax mode, but not in strict mode
from datetime import datetime
from pydantic import BaseModel
class Event(BaseModel):
dt: datetime = None
event = Event(dt='2032-04-23T10:20:30.400+02:30')
print(event.model_dump())
"""
{'dt': datetime.datetime(2032, 4, 23, 10, 20, 30, 400000, tzinfo=TzInfo(+02:30))}
"""
datetime.date¶
-
datefields will accept values of type:date; an existingdateobjectintorfloat; handled the same as described fordatetimeabovestr; the following formats are accepted:YYYY-MM-DDintorfloatas a string (assumed as Unix time)
from datetime import date
from pydantic import BaseModel
class Birthday(BaseModel):
d: date = None
my_birthday = Birthday(d=1679616000.0)
print(my_birthday.model_dump())
#> {'d': datetime.date(2023, 3, 24)}
datetime.time¶
-
timefields will accept values of type:time; an existingtimeobjectstr; the following formats are accepted:HH:MM[:SS[.ffffff]][Z or [±]HH[:]MM]
from datetime import time
from pydantic import BaseModel
class Meeting(BaseModel):
t: time = None
m = Meeting(t=time(4, 8, 16))
print(m.model_dump())
#> {'t': datetime.time(4, 8, 16)}
datetime.timedelta¶
-
timedeltafields will accept values of type:timedelta; an existingtimedeltaobjectintorfloat; assumed to be secondsstr; the following formats are accepted:[-][DD]D[,][HH:MM:]SS[.ffffff]- Ex:
'1d,01:02:03.000004'or'1D01:02:03.000004'or'01:02:03'
- Ex:
[±]P[DD]DT[HH]H[MM]M[SS]S(ISO 8601 format for timedelta)
from datetime import timedelta
from pydantic import BaseModel
class Model(BaseModel):
td: timedelta = None
m = Model(td='P3DT12H30M5S')
print(m.model_dump())
#> {'td': datetime.timedelta(days=3, seconds=45005)}
Number Types¶
Pydantic supports the following numeric types from the Python standard library:
int¶
- Pydantic uses
int(v)to coerce types to anint; see Data conversion for details on loss of information during data conversion.
float¶
- Pydantic uses
float(v)to coerce values to floats.
enum.IntEnum¶
- Validation: Pydantic checks that the value is a valid
IntEnuminstance. - Validation for subclass of
enum.IntEnum: checks that the value is a valid member of the integer enum; see Enums and Choices for more details.
decimal.Decimal¶
- Validation: Pydantic attempts to convert the value to a string, then passes the string to
Decimal(v). - Serialization: Pydantic serializes
Decimaltypes as strings. You can use a custom serializer to override this behavior if desired. For example:
from decimal import Decimal
from typing_extensions import Annotated
from pydantic import BaseModel, PlainSerializer
class Model(BaseModel):
x: Decimal
y: Annotated[
Decimal,
PlainSerializer(
lambda x: float(x), return_type=float, when_used='json'
),
]
my_model = Model(x=Decimal('1.1'), y=Decimal('2.1'))
print(my_model.model_dump()) # (1)!
#> {'x': Decimal('1.1'), 'y': Decimal('2.1')}
print(my_model.model_dump(mode='json')) # (2)!
#> {'x': '1.1', 'y': 2.1}
print(my_model.model_dump_json()) # (3)!
#> {"x":"1.1","y":2.1}
- Using
model_dump, bothxandyremain instances of theDecimaltype - Using
model_dumpwithmode='json',xis serialized as astring, andyis serialized as afloatbecause of the custom serializer applied. - Using
model_dump_json,xis serialized as astring, andyis serialized as afloatbecause of the custom serializer applied.
Enum¶
Pydantic uses Python's standard enum classes to define choices.
enum.Enum checks that the value is a valid Enum instance.
Subclass of enum.Enum checks that the value is a valid member of the enum.
from enum import Enum, IntEnum
from pydantic import BaseModel, ValidationError
class FruitEnum(str, Enum):
pear = 'pear'
banana = 'banana'
class ToolEnum(IntEnum):
spanner = 1
wrench = 2
class CookingModel(BaseModel):
fruit: FruitEnum = FruitEnum.pear
tool: ToolEnum = ToolEnum.spanner
print(CookingModel())
#> fruit=<FruitEnum.pear: 'pear'> tool=<ToolEnum.spanner: 1>
print(CookingModel(tool=2, fruit='banana'))
#> fruit=<FruitEnum.banana: 'banana'> tool=<ToolEnum.wrench: 2>
try:
CookingModel(fruit='other')
except ValidationError as e:
print(e)
"""
1 validation error for CookingModel
fruit
Input should be 'pear' or 'banana' [type=enum, input_value='other', input_type=str]
"""
Lists and Tuples¶
list¶
Allows list, tuple, set, frozenset, deque, or generators and casts to a list.
When a generic parameter is provided, the appropriate validation is applied to all items of the list.
typing.List¶
Handled the same as list above.
from typing import List, Optional
from pydantic import BaseModel
class Model(BaseModel):
simple_list: Optional[list] = None
list_of_ints: Optional[List[int]] = None
print(Model(simple_list=['1', '2', '3']).simple_list)
#> ['1', '2', '3']
print(Model(list_of_ints=['1', '2', '3']).list_of_ints)
#> [1, 2, 3]
tuple¶
Allows list, tuple, set, frozenset, deque, or generators and casts to a tuple.
When generic parameters are provided, the appropriate validation is applied to the respective items of the tuple
typing.Tuple¶
Handled the same as tuple above.
from typing import Optional, Tuple
from pydantic import BaseModel
class Model(BaseModel):
simple_tuple: Optional[tuple] = None
tuple_of_different_types: Optional[Tuple[int, float, bool]] = None
print(Model(simple_tuple=[1, 2, 3, 4]).simple_tuple)
#> (1, 2, 3, 4)
print(Model(tuple_of_different_types=[3, 2, 1]).tuple_of_different_types)
#> (3, 2.0, True)
typing.NamedTuple¶
Subclasses of typing.NamedTuple are similar to tuple, but create instances of the given namedtuple class.
Subclasses of collections.namedtuple are similar to subclass of typing.NamedTuple, but since field types are not specified,
all fields are treated as having type Any.
from typing import NamedTuple
from pydantic import BaseModel, ValidationError
class Point(NamedTuple):
x: int
y: int
class Model(BaseModel):
p: Point
try:
Model(p=('1.3', '2'))
except ValidationError as e:
print(e)
"""
1 validation error for Model
p.0
Input should be a valid integer, unable to parse string as an integer [type=int_parsing, input_value='1.3', input_type=str]
"""
Deque¶
deque¶
Allows list, tuple, set, frozenset, deque, or generators and casts to a deque.
When generic parameters are provided, the appropriate validation is applied to the respective items of the deque.
typing.Deque¶
Handled the same as deque above.
from typing import Deque, Optional
from pydantic import BaseModel
class Model(BaseModel):
deque: Optional[Deque[int]] = None
print(Model(deque=[1, 2, 3]).deque)
#> deque([1, 2, 3])
Sets¶
set¶
Allows list, tuple, set, frozenset, deque, or generators and casts to a set.
When a generic parameter is provided, the appropriate validation is applied to all items of the set.
typing.Set¶
Handled the same as set above.
from typing import Optional, Set
from pydantic import BaseModel
class Model(BaseModel):
simple_set: Optional[set] = None
set_of_ints: Optional[Set[int]] = None
print(Model(simple_set={'1', '2', '3'}).simple_set)
#> {'1', '2', '3'}
print(Model(simple_set=['1', '2', '3']).simple_set)
#> {'1', '2', '3'}
print(Model(set_of_ints=['1', '2', '3']).set_of_ints)
#> {1, 2, 3}
frozenset¶
Allows list, tuple, set, frozenset, deque, or generators and casts to a frozenset.
When a generic parameter is provided, the appropriate validation is applied to all items of the frozen set.
typing.FrozenSet¶
Handled the same as frozenset above.
from typing import FrozenSet, Optional
from pydantic import BaseModel
class Model(BaseModel):
simple_frozenset: Optional[frozenset] = None
frozenset_of_ints: Optional[FrozenSet[int]] = None
m1 = Model(simple_frozenset=['1', '2', '3'])
print(type(m1.simple_frozenset))
#> <class 'frozenset'>
print(sorted(m1.simple_frozenset))
#> ['1', '2', '3']
m2 = Model(frozenset_of_ints=['1', '2', '3'])
print(type(m2.frozenset_of_ints))
#> <class 'frozenset'>
print(sorted(m2.frozenset_of_ints))
#> [1, 2, 3]
Other Iterables¶
typing.Sequence¶
This is intended for use when the provided value should meet the requirements of the Sequence ABC, and it is
desirable to do eager validation of the values in the container. Note that when validation must be performed on the
values of the container, the type of the container may not be preserved since validation may end up replacing values.
We guarantee that the validated value will be a valid typing.Sequence, but it may have a different type than was
provided (generally, it will become a list).
typing.Iterable¶
This is intended for use when the provided value may be an iterable that shouldn't be consumed.
See Infinite Generators below for more detail on parsing and validation.
Similar to typing.Sequence, we guarantee that the validated result will be a valid typing.Iterable,
but it may have a different type than was provided. In particular, even if a non-generator type such as a list
is provided, the post-validation value of a field of type typing.Iterable will be a generator.
Here is a simple example using typing.Sequence:
from typing import Sequence
from pydantic import BaseModel
class Model(BaseModel):
sequence_of_ints: Sequence[int] = None
print(Model(sequence_of_ints=[1, 2, 3, 4]).sequence_of_ints)
#> [1, 2, 3, 4]
print(Model(sequence_of_ints=(1, 2, 3, 4)).sequence_of_ints)
#> (1, 2, 3, 4)
Infinite Generators¶
If you have a generator you want to validate, you can still use Sequence as described above.
In that case, the generator will be consumed and stored on the model as a list and its values will be
validated against the type parameter of the Sequence (e.g. int in Sequence[int]).
However, if you have a generator that you don't want to be eagerly consumed (e.g. an infinite
generator or a remote data loader), you can use a field of type Iterable:
from typing import Iterable
from pydantic import BaseModel
class Model(BaseModel):
infinite: Iterable[int]
def infinite_ints():
i = 0
while True:
yield i
i += 1
m = Model(infinite=infinite_ints())
print(m)
"""
infinite=ValidatorIterator(index=0, schema=Some(Int(IntValidator { strict: false })))
"""
for i in m.infinite:
print(i)
#> 0
#> 1
#> 2
#> 3
#> 4
#> 5
#> 6
#> 7
#> 8
#> 9
#> 10
if i == 10:
break
Warning
During initial validation, Iterable fields only perform a simple check that the provided argument is iterable.
To prevent it from being consumed, no validation of the yielded values is performed eagerly.
Though the yielded values are not validated eagerly, they are still validated when yielded, and will raise a
ValidationError at yield time when appropriate:
from typing import Iterable
from pydantic import BaseModel, ValidationError
class Model(BaseModel):
int_iterator: Iterable[int]
def my_iterator():
yield 13
yield '27'
yield 'a'
m = Model(int_iterator=my_iterator())
print(next(m.int_iterator))
#> 13
print(next(m.int_iterator))
#> 27
try:
next(m.int_iterator)
except ValidationError as e:
print(e)
"""
1 validation error for ValidatorIterator
2
Input should be a valid integer, unable to parse string as an integer [type=int_parsing, input_value='a', input_type=str]
"""
Mapping Types¶
dict¶
dict(v) is used to attempt to convert a dictionary. see typing.Dict below for sub-type constraints.
from pydantic import BaseModel, ValidationError
class Model(BaseModel):
x: dict
m = Model(x={'foo': 1})
print(m.model_dump())
#> {'x': {'foo': 1}}
try:
Model(x='test')
except ValidationError as e:
print(e)
"""
1 validation error for Model
x
Input should be a valid dictionary [type=dict_type, input_value='test', input_type=str]
"""
typing.Dict¶
from typing import Dict
from pydantic import BaseModel, ValidationError
class Model(BaseModel):
x: Dict[str, int]
m = Model(x={'foo': 1})
print(m.model_dump())
#> {'x': {'foo': 1}}
try:
Model(x={'foo': '1'})
except ValidationError as e:
print(e)
"""
1 validation error for Model
x
Input should be a valid dictionary [type=dict_type, input_value='test', input_type=str]
"""
TypedDict¶
Note
This is a new feature of the Python standard library as of Python 3.8.
Because of limitations in typing.TypedDict before 3.12, the typing-extensions
package is required for Python <3.12. You'll need to import TypedDict from typing_extensions instead of typing and will
get a build time error if you don't.
TypedDict declares a dictionary type that expects all of
its instances to have a certain set of keys, where each key is associated with a value of a consistent type.
It is same as dict but Pydantic will validate the dictionary since keys are annotated.
from typing_extensions import TypedDict
from pydantic import TypeAdapter, ValidationError
class User(TypedDict):
name: str
id: int
ta = TypeAdapter(User)
print(ta.validate_python({'name': 'foo', 'id': 1}))
#> {'name': 'foo', 'id': 1}
try:
ta.validate_python({'name': 'foo'})
except ValidationError as e:
print(e)
"""
1 validation error for typed-dict
id
Field required [type=missing, input_value={'name': 'foo'}, input_type=dict]
"""
You can define __pydantic_config__ to change the model inherited from TypedDict.
See the ConfigDict API reference for more details.
from typing import Optional
from typing_extensions import TypedDict
from pydantic import ConfigDict, TypeAdapter, ValidationError
# `total=False` means keys are non-required
class UserIdentity(TypedDict, total=False):
name: Optional[str]
surname: str
class User(TypedDict):
__pydantic_config__ = ConfigDict(extra='forbid')
identity: UserIdentity
age: int
ta = TypeAdapter(User)
print(
ta.validate_python(
{'identity': {'name': 'Smith', 'surname': 'John'}, 'age': 37}
)
)
#> {'identity': {'name': 'Smith', 'surname': 'John'}, 'age': 37}
print(
ta.validate_python(
{'identity': {'name': None, 'surname': 'John'}, 'age': 37}
)
)
#> {'identity': {'name': None, 'surname': 'John'}, 'age': 37}
print(ta.validate_python({'identity': {}, 'age': 37}))
#> {'identity': {}, 'age': 37}
try:
ta.validate_python(
{'identity': {'name': ['Smith'], 'surname': 'John'}, 'age': 24}
)
except ValidationError as e:
print(e)
"""
1 validation error for typed-dict
identity.name
Input should be a valid string [type=string_type, input_value=['Smith'], input_type=list]
"""
try:
ta.validate_python(
{
'identity': {'name': 'Smith', 'surname': 'John'},
'age': '37',
'email': '[email protected]',
}
)
except ValidationError as e:
print(e)
"""
1 validation error for typed-dict
email
Extra inputs are not permitted [type=extra_forbidden, input_value='[email protected]', input_type=str]
"""
Callable¶
See below for more detail on parsing and validation
Fields can also be of type Callable:
from typing import Callable
from pydantic import BaseModel
class Foo(BaseModel):
callback: Callable[[int], int]
m = Foo(callback=lambda x: x)
print(m)
#> callback=<function <lambda> at 0x0123456789ab>
Warning
Callable fields only perform a simple check that the argument is callable; no validation of arguments, their types, or the return type is performed.
IP Address Types¶
ipaddress.IPv4Address: Uses the type itself for validation by passing the value toIPv4Address(v).ipaddress.IPv4Interface: Uses the type itself for validation by passing the value toIPv4Address(v).ipaddress.IPv4Network: Uses the type itself for validation by passing the value toIPv4Network(v).ipaddress.IPv6Address: Uses the type itself for validation by passing the value toIPv6Address(v).ipaddress.IPv6Interface: Uses the type itself for validation by passing the value toIPv6Interface(v).ipaddress.IPv6Network: Uses the type itself for validation by passing the value toIPv6Network(v).
See Network Types for other custom IP address types.
UUID¶
For UUID, Pydantic tries to use the type itself for validation by passing the value to UUID(v).
There's a fallback to UUID(bytes=v) for bytes and bytearray.
In case you want to constrain the UUID version, you can check the following types:
UUID1: requires UUID version 1.UUID3: requires UUID version 3.UUID4: requires UUID version 4.UUID5: requires UUID version 5.
Union¶
Pydantic has extensive support for union validation, both typing.Union and Python 3.10's pipe syntax (A | B) are supported.
Read more in the Unions section of the concepts docs.
Type and TypeVar¶
type¶
Pydantic supports the use of type[T] to specify that a field may only accept classes (not instances)
that are subclasses of T.
typing.Type¶
Handled the same as type above.
from typing import Type
from pydantic import BaseModel, ValidationError
class Foo:
pass
class Bar(Foo):
pass
class Other:
pass
class SimpleModel(BaseModel):
just_subclasses: Type[Foo]
SimpleModel(just_subclasses=Foo)
SimpleModel(just_subclasses=Bar)
try:
SimpleModel(just_subclasses=Other)
except ValidationError as e:
print(e)
"""
1 validation error for SimpleModel
just_subclasses
Input should be a subclass of Foo [type=is_subclass_of, input_value=<class '__main__.Other'>, input_type=type]
"""
You may also use Type to specify that any class is allowed.
from typing import Type
from pydantic import BaseModel, ValidationError
class Foo:
pass
class LenientSimpleModel(BaseModel):
any_class_goes: Type
LenientSimpleModel(any_class_goes=int)
LenientSimpleModel(any_class_goes=Foo)
try:
LenientSimpleModel(any_class_goes=Foo())
except ValidationError as e:
print(e)
"""
1 validation error for LenientSimpleModel
any_class_goes
Input should be a type [type=is_type, input_value=<__main__.Foo object at 0x0123456789ab>, input_type=Foo]
"""
typing.TypeVar¶
TypeVar is supported either unconstrained, constrained or with a bound.
from typing import TypeVar
from pydantic import BaseModel
Foobar = TypeVar('Foobar')
BoundFloat = TypeVar('BoundFloat', bound=float)
IntStr = TypeVar('IntStr', int, str)
class Model(BaseModel):
a: Foobar # equivalent of ": Any"
b: BoundFloat # equivalent of ": float"
c: IntStr # equivalent of ": Union[int, str]"
print(Model(a=[1], b=4.2, c='x'))
#> a=[1] b=4.2 c='x'
# a may be None
print(Model(a=None, b=1, c=1))
#> a=None b=1.0 c=1
None Types¶
None, type(None), or Literal[None] are all equivalent according to the typing specification.
Allows only None value.
Strings¶
str: Strings are accepted as-is. bytes and bytearray are converted using v.decode().
Enums inheriting fromstrare converted usingv.value`. All other types cause an error.
Strings aren't Sequences
While instances of str are technically valid instances of the Sequence[str] protocol from a type-checker's point of
view, this is frequently not intended as is a common source of bugs.
As a result, Pydantic raises a ValidationError if you attempt to pass a str or bytes instance into a field of type
Sequence[str] or Sequence[bytes]:
from typing import Optional, Sequence
from pydantic import BaseModel, ValidationError
class Model(BaseModel):
sequence_of_strs: Optional[Sequence[str]] = None
sequence_of_bytes: Optional[Sequence[bytes]] = None
print(Model(sequence_of_strs=['a', 'bc']).sequence_of_strs)
#> ['a', 'bc']
print(Model(sequence_of_strs=('a', 'bc')).sequence_of_strs)
#> ('a', 'bc')
print(Model(sequence_of_bytes=[b'a', b'bc']).sequence_of_bytes)
#> [b'a', b'bc']
print(Model(sequence_of_bytes=(b'a', b'bc')).sequence_of_bytes)
#> (b'a', b'bc')
try:
Model(sequence_of_strs='abc')
except ValidationError as e:
print(e)
"""
1 validation error for Model
sequence_of_strs
'str' instances are not allowed as a Sequence value [type=sequence_str, input_value='abc', input_type=str]
"""
try:
Model(sequence_of_bytes=b'abc')
except ValidationError as e:
print(e)
"""
1 validation error for Model
sequence_of_bytes
'bytes' instances are not allowed as a Sequence value [type=sequence_str, input_value=b'abc', input_type=bytes]
"""
Bytes¶
bytes are accepted as-is. bytearray is converted using bytes(v). str are converted using v.encode(). int, float, and Decimal are coerced using str(v).encode(). See ByteSize for more details.
typing.Literal¶
Pydantic supports the use of typing.Literal as a lightweight way to specify that a field may accept only specific literal values:
from typing import Literal
from pydantic import BaseModel, ValidationError
class Pie(BaseModel):
flavor: Literal['apple', 'pumpkin']
Pie(flavor='apple')
Pie(flavor='pumpkin')
try:
Pie(flavor='cherry')
except ValidationError as e:
print(str(e))
"""
1 validation error for Pie
flavor
Input should be 'apple' or 'pumpkin' [type=literal_error, input_value='cherry', input_type=str]
"""
One benefit of this field type is that it can be used to check for equality with one or more specific values without needing to declare custom validators:
from typing import ClassVar, List, Literal, Union
from pydantic import BaseModel, ValidationError
class Cake(BaseModel):
kind: Literal['cake']
required_utensils: ClassVar[List[str]] = ['fork', 'knife']
class IceCream(BaseModel):
kind: Literal['icecream']
required_utensils: ClassVar[List[str]] = ['spoon']
class Meal(BaseModel):
dessert: Union[Cake, IceCream]
print(type(Meal(dessert={'kind': 'cake'}).dessert).__name__)
#> Cake
print(type(Meal(dessert={'kind': 'icecream'}).dessert).__name__)
#> IceCream
try:
Meal(dessert={'kind': 'pie'})
except ValidationError as e:
print(str(e))
"""
2 validation errors for Meal
dessert.Cake.kind
Input should be 'cake' [type=literal_error, input_value='pie', input_type=str]
dessert.IceCream.kind
Input should be 'icecream' [type=literal_error, input_value='pie', input_type=str]
"""
With proper ordering in an annotated Union, you can use this to parse types of decreasing specificity:
from typing import Literal, Optional, Union
from pydantic import BaseModel
class Dessert(BaseModel):
kind: str
class Pie(Dessert):
kind: Literal['pie']
flavor: Optional[str]
class ApplePie(Pie):
flavor: Literal['apple']
class PumpkinPie(Pie):
flavor: Literal['pumpkin']
class Meal(BaseModel):
dessert: Union[ApplePie, PumpkinPie, Pie, Dessert]
print(type(Meal(dessert={'kind': 'pie', 'flavor': 'apple'}).dessert).__name__)
#> ApplePie
print(type(Meal(dessert={'kind': 'pie', 'flavor': 'pumpkin'}).dessert).__name__)
#> PumpkinPie
print(type(Meal(dessert={'kind': 'pie'}).dessert).__name__)
#> Dessert
print(type(Meal(dessert={'kind': 'cake'}).dessert).__name__)
#> Dessert
typing.Any¶
Allows any value, including None.
typing.Annotated¶
Allows wrapping another type with arbitrary metadata, as per PEP-593. The Annotated hint may contain a single call to the Field function, but otherwise the additional metadata is ignored and the root type is used.
typing.Pattern¶
Will cause the input value to be passed to re.compile(v) to create a regular expression pattern.
pathlib.Path¶
Simply uses the type itself for validation by passing the value to Path(v).