datamodel-code-generator icon indicating copy to clipboard operation
datamodel-code-generator copied to clipboard

Support `"unevaluatedProperties"`

Open evvaaaa opened this issue 10 months ago • 1 comments

I have a jsonschema

{
    "title": "resource",
    "type": "object",
    "allOf": [
        { "$ref": "#/$defs/PartialResource" }
    ],
    "$defs": {
        "PartialResource": {
            "title": "partial_resource",
            "properties": {
                "spec": {
                    "title": "spec",
                    "type": "string"
                },
                "resource_kwargs": {
                    "title": "resource_kwargs",
                    "type": "object"
                },
                "resource_path": {
                    "title": "resource_path",
                    "type": "string"
                },
                "root": {
                    "title": "root",
                    "type": "string"
                },
                "uid": {
                    "title": "uid",
                    "type": "string"
                }
            },
            "required": [
                "resource_kwargs",
                "resource_path",
                "root",
                "spec",
                "uid"
            ]
        }
    },
    "properties": {
        "path_semantics": {
            "title": "path_semantics",
            "type": "string",
            "enum": [
                "posix",
                "windows"
            ]
        },
        "run_start": {
            "title": "run_start",
            "type": "string"
        }
    },
    "unevaluatedProperties": false
}

which generates a BaseModel:

class PartialResource(BaseModel):
    spec: str = Field(..., title="spec")
    resource_kwargs: Dict[str, Any] = Field(..., title="resource_kwargs")
    resource_path: str = Field(..., title="resource_path")
    root: str = Field(..., title="root")
    uid: str = Field(..., title="uid")


class Resource(PartialResource):
    path_semantics: Optional[PathSemantics] = Field(None, title="path_semantics")
    run_start: Optional[str] = Field(None, title="run_start")

The "unevaluatedProperties" in the schema works in the same way as "additionalProperties", but allows the elements declared in subschema.

For analogous behaviour in the generated BaseModel, we could change

https://github.com/koxudaxi/datamodel-code-generator/blob/396601ee7d8bf07729368954f30c67e56926a825/datamodel_code_generator/model/pydantic_v2/base_model.py#L240-L247

to also check for "unevaluatedProperties": false and use "forbid".

evvaaaa avatar Jan 09 '25 12:01 evvaaaa

PR welcome.

gaborbernat avatar Feb 06 '25 20:02 gaborbernat