datamodel-code-generator
datamodel-code-generator copied to clipboard
Missing hash function for a class
Describe the bug
When working with Set collection, It is not possible to perform add operations on the set collection due to missing hash function. One gets following error:
myModel.vocab.fruits.category.add(model.Apple(apple={}))
TypeError: unhashable type: 'Apple'
To Reproduce
Example schema:
{
"title": "FruitVocab",
"type": "object",
"properties": {
"Vocab": {
"type": "object",
"properties": {
"Fruits": {
"title": "Fruits",
"type": "object",
"properties": {
"Category": {
"title": "Type",
"type": "array",
"uniqueItems": true,
"items": {
"type": "object",
"anyOf": [
{
"title": "Apple",
"type": "object",
"properties": {
"Apple": {
"title": "Apple",
"type": "object",
"properties": {},
"required": [],
"additionalProperties": false
}
},
"additionalProperties": false
},
{
"title": "Mango",
"type": "object",
"properties": {
"Mango": {
"title": "Mango",
"type": "object",
"properties": {},
"required": [],
"additionalProperties": false
}
},
"additionalProperties": false
},
{
"title": "Banana",
"type": "object",
"properties": {
"Banana": {
"title": "Banana",
"type": "object",
"properties": {},
"required": [],
"additionalProperties": false
}
},
"additionalProperties": false
}
],
"default": {
"Apple": {}
}
}
}
},
"required": [],
"additionalProperties": false
}
},
"required": []
}
},
"additionalProperties": false,
"required": []
}
Used commandline:
$ datamodel-codegen --use-standard-collections --use-unique-items-as-set --use-annotated --use-title-as-name --use-subclass-enum --disable-appending-item-suffix --input-file-type jsonschema --input errorJsonSchema.json --output TestMain.py --output-model-type pydantic_v2.BaseModel --allow-population-by-field-name --snake-case-field
Used Model Code:
import TestMain as model
myModel = model.FruitVocab()
myModel.vocab = model.Vocab()
myModel.vocab.fruits = model.Fruits()
myModel.vocab.fruits.category = set()
myModel.vocab.fruits.category.add(model.Apple(apple={}))
Expected behavior One should be able to add objects to a set.
import TestMain as model
myModel = model.FruitVocab()
myModel.vocab = model.Vocab()
myModel.vocab.fruits = model.Fruits()
myModel.vocab.fruits.category = set()
myModel.vocab.fruits.category.add(model.Apple(apple={}))
print(myModel.model_dump_json(indent=2,by_alias=True))
Currently adding __hash__ = object.__hash__ to the Apple Class solves the error.
class Apple(BaseModel):
# ADDING THIS WORKS
__hash__ = object.__hash__
model_config = ConfigDict(
extra='forbid',
populate_by_name=True,
)
apple: Annotated[
Optional[dict[str, Any]], Field(alias='Apple', title='Apple')
] = None
So this __hash__ = object.__hash__ needs to be autogenerated by the code-generator
Version:
- OS: MacOS
- Python version: 3.10
- datamodel-code-generator version: 0.22.0
Additional context Add any other context about the problem here.
Is there any workaround for this? Can I somehow add the hash method programatically?
__hash__ = object.__hash__ would also be a nice addition to RootModel .
I'm getting TypeError: unhashable type: for a RootModel, and adding the __hash__ function manually solves the issues.