How to use two variable types in a pydantic.BaseModel with typing.Union?

Mirrah

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?

Matteo Zanoni

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 and Decimal are coerced using str(v), bytes and bytearray are converted using v.decode(), enums inheriting from str are converted using v.value, and all other types cause an error

bytes are accepted as-is, bytearray is converted using bytes(v), str are converted using v.encode(), and int, float, and Decimal are coerced using str(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.

edited at
0

Comments

0 comments
Login to comment

Related

How to use a union of two types

How to use values from list to validate some calculations in pydantic BaseModel?

How to mock pydantic BaseModel that expects a Response object?

Pydantic is confused with my types and their union

Pydantic: dataclass vs BaseModel

How to manage situational-optional input parameters using pydantic BaseModel?

How to partially update data with FastAPI and PyDantic BaseModel using PATCH

How to use validators in Strict Types of Pydantic like StrictStr?

Including special character in Basemodel for Pydantic

FlowJS: How to use union types and boolean literals

How to use TypeScript union types in react

How to use generic type and union types in typescript

Can I use the Union and Optional types from the typing module when creating a dataclass?

problem in typing Promise that returns a Union of types

Union types & duck-typing in typescript

How to make Pylance and Pydantic understand each other when instantiating BaseModel class from external data?

Is it possible to use variable values as one of the union types in Typescript?

Allowing the use of two variable types seamlessly

Set default based on another field in pydantic BaseModel

Pydantic BaseModel schema and instance serialization/deserialization not working

Is it possible to make different versions of the same pydantic basemodel?

How to use a union along with two structs + more

How to use UNION with two selects and some JOINS

How to create multiple constrained types in Pydantic

pydantic: how to make a choice of types for a field?

Union of two variable sets

How two types of variable usage behave different

how to declare a variable with two types via typescript

How to merge two lists with different variable types