I need my model to accept either a bytes type variable or a string type variable and to raise an exception if any other type was passed.
from typing import Union
from pydantic import BaseModel
class MyModel(BaseModel):
a: Union[bytes, str]
m1 = MyModel(a='123')
m2 = MyModel(a=b'123')
print(type(m1.a))
print(type(m2.a))
In my case the model interprets both bytes and string as bytes.
Output:
<class 'bytes'>
<class 'bytes'>
Desired output:
<class 'str'>
<class 'bytes'>
The desired output above can be achieved if I re-assign member a:
m1 = MyModel(a='123')
m1.a = '123'
Is it possible to get it in one go?
The problem you are facing is that the str
type does some automatic conversions (here in the docs):
strings are accepted as-is,
int
float
andDecimal
are coerced usingstr(v)
,bytes
andbytearray
are converted usingv.decode()
, enums inheriting fromstr
are converted usingv.value
, and all other types cause an error
bytes
are accepted as-is,bytearray
is converted usingbytes(v)
,str
are converted usingv.encode()
, andint
,float
, andDecimal
are coerced usingstr(v).encode()
You can use StrictTypes
to avoid automatic conversion between compatible types (e.g.: str
and bytes
):
from typing import Union
from pydantic import BaseModel, StrictStr, StrictBytes
class MyModel(BaseModel):
a: Union[StrictStr, StrictBytes]
m1 = MyModel(a='123')
m2 = MyModel(a=b'123')
print(type(m1.a))
print(type(m2.a))
Output will be as expected:
<class 'str'>
<class 'bytes'>
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments