In my situation I get a response from an API which follows the structure of MyGenericModel. After I parse the response using MyGenericModel, I want to check if it belongs to my set defined in MyEnum. If it does I want to continue with it, if not.. then we proceed further.
When I call
MyGenericModel(value_one="a", value_two="b") in MyEnum
I get a TypeError as response.When I call
MySpecificModel() in MyEnum
I get a TypeError as response.When I call
MySpecificModel() == MyGenericModel(value_one="a", value_two="b")
I get 'True' as response.
here is a small simplified example of my code:
from pydantic import BaseModel
from enum import Enum
class MyGenericModel(BaseModel):
value_one: str
value_two: str
def __eq__(self, other):
return self.model_dump() == other.model_dump()
class MySpecificModel(MyGenericModel):
value_one: str = "a"
value_two: str = "b"
class MyEnum(Enum):
my_model = MySpecificModel()
# This is true
MyGenericModel(value_one="a", value_two="b") == MySpecificModel()
# This fails - and I want to be true
MyGenericModel(value_one="a", value_two="b") in MyEnum
How to solve this issue?
In my situation I get a response from an API which follows the structure of MyGenericModel. After I parse the response using MyGenericModel, I want to check if it belongs to my set defined in MyEnum. If it does I want to continue with it, if not.. then we proceed further.
When I call
MyGenericModel(value_one="a", value_two="b") in MyEnum
I get a TypeError as response.When I call
MySpecificModel() in MyEnum
I get a TypeError as response.When I call
MySpecificModel() == MyGenericModel(value_one="a", value_two="b")
I get 'True' as response.
here is a small simplified example of my code:
from pydantic import BaseModel
from enum import Enum
class MyGenericModel(BaseModel):
value_one: str
value_two: str
def __eq__(self, other):
return self.model_dump() == other.model_dump()
class MySpecificModel(MyGenericModel):
value_one: str = "a"
value_two: str = "b"
class MyEnum(Enum):
my_model = MySpecificModel()
# This is true
MyGenericModel(value_one="a", value_two="b") == MySpecificModel()
# This fails - and I want to be true
MyGenericModel(value_one="a", value_two="b") in MyEnum
How to solve this issue?
Share edited Mar 17 at 13:12 zwep asked Mar 14 at 13:55 zwepzwep 1,3381 gold badge13 silver badges27 bronze badges 10 | Show 5 more comments1 Answer
Reset to default 0The problem here was that the 'in' operator was not properly defined in this situation.
The 'in' operator calls the '_contains_' magic method, but this should be defined in the class that creates the Enum class!
In order to do that, we need to use the EnumMeta class, inherit from that, and define a new class. This new class will be used as metaclass in MyEnum:
from enum import EnumMeta
class MetaEnum(EnumMeta):
def __contains__(cls, item):
return any([item == x.value for x in cls.__members__.values()])
class MyEnum(Enum, metaclass=MetaEnum):
my_model = MySpecificModel()
Using this to redefine MyEnum allows us to check if a generic class is in the Enum, when that is initialized with attributes that make it essentially identical to the specific class:
# This is true
MyGenericModel(value_one="a", value_two="b") == MySpecificModel()
# This is now also True
MyGenericModel(value_one="a", value_two="b") in MyEnum
I have learned a lot from this post about metaclasses:
What are metaclasses in Python?
MyGenericModel(value_one=“a”, value_two=“c”)
andMyGenericModel(value_one=“a”, value_two=“a”)
both should throw a validation error, or is it acceptableMyGenericModel(value_one=“a”, value_two=“a”)
? – Serhii Fomenko Commented Mar 14 at 14:53API
, and only writes data to the database ifMyGenericModel(value_one=“a”, value_two=“b”)
, for this you could use validators on thepydantic
model and check the modeltry -> MyGenericModel(...); doSomething() -> catch ValidationError -> continue
. As I understand your question, is this what you want to do:value not in MyEnum -> then continue
? If not, please provide an example of the usage in the question. – Serhii Fomenko Commented Mar 14 at 15:59MyGenericModel
) to theMyEnum
type, like this. I am not sure if this is a good practice though. – ken Commented Mar 14 at 16:21self
in the hash calculation causes mismatches. Instead, I suggested calculating the hash using only the field values ofself
that determine equality. – ken Commented Mar 16 at 17:50