Describe the bug
allOf with a single $ref
with a local json-pointer in schemaA.json is not resolved correctly with schemaA.json is itself referenced from schemaB.json.
It seems like schemaB.json (where no definitions exist) is passed as self.raw_obj
to get_model_by_path()
but it should be schemaB.json. get_model_by_path()
tries to look up the path but fails.
To Reproduce
schemaA
{
"definitions": {
"generated": {
"type": "object",
"title": "SchemaAGenerated",
"properties": {
"test": {
"title": "test",
"type": "string"
}
}
}
},
"title": "SchemaA",
"allOf": [
{
"$ref": "#/definitions/generated"
}
]
}
schemaB.json
{
"allOf": [
{
"$ref": "SchemaA.json"
}
],
"type": "object",
"title": "SchemaB"
}
Used commandline:
$ datamodel-codegen --input schemaB.json --output model.py --use-title-as-name
Error:
File ".venv\lib\site-packages\datamodel_code_generator\parser\jsonschema.py", line 1807, in _parse_file
self.parse_obj(obj_name, root_obj, path_parts or ['#'])
File ".venv\lib\site-packages\datamodel_code_generator\parser\jsonschema.py", line 1667, in parse_obj
self.parse_all_of(name, obj, path)
File ".venv\lib\site-packages\datamodel_code_generator\parser\jsonschema.py", line 871, in parse_all_of
if get_model_by_path(self.raw_obj, single_obj.ref[2:].split('/')).get(
File ".venv\lib\site-packages\datamodel_code_generator\parser\jsonschema.py", line 87, in get_model_by_path
model = get_model_by_path(schema[keys[0]], keys[1:]) # type: ignore
KeyError: 'definitions'
Expected behavior
No exception and the following model.py
class SchemaAGenerated(BaseModel):
test: Optional[str] = Field(
None, title="test"
)
class SchemaA(SchemaAGenerated):
pass
class SchemaB(SchemaA):
pass
or, even better, with the empty class SchemaA merged with SchemaAGenerated
class SchemaA(BaseModel):
test: Optional[str] = Field(
None, title="test"
)
class SchemaB(SchemaA):
pass
Workarounds:
replacing
"allOf": [
{
"$ref": "#/definitions/generated"
}
]
with
"$ref": "#/definitions/generated"
works, but produces
class SchemaAGenerated(BaseModel):
test: Optional[str] = Field(None, title='test')
class SchemaA(BaseModel):
__root__: SchemaAGenerated = Field(..., title='SchemaA')
class SchemaB(BaseModel):
pass
even with --collapse-root-models
.
Having an array of two $refs
in allOf also works as expected:
"allOf": [
{
"$ref": "#/definitions/generated"
},
{
}
]
Version:
Pay now to fund the work behind this issue.
Get updates on progress being made.
Maintainer is rewarded once the issue is completed.
You're funding impactful open source efforts
You want to contribute to this effort
You want to get funding like this too