Search code examples
jsonschemapython-jsonschema

python jsonschema not recognising `"allOf"` with `$ref`


I have some jsonschema for a dictionary Resource, containing a $defs PartialResource.

{
    "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"
        }
    },
    "additionalProperties": false
}

It's structured this way so that datamodel-codegen can generate two TypedDicts, which it correctly does:

class PartialResource(TypedDict):
    spec: str
    resource_kwargs: Dict[str, Any]
    resource_path: str
    root: str
    uid: str


class Resource(PartialResource):
    path_semantics: NotRequired[Literal["posix", "windows"]]
    run_start: NotRequired[str]

When I actually try to use the schema with the jsonschema Draft202012Validator it doesn't seem to use the PartialResource definition:

    {'path_semantics': 'posix',
     'uid': 'e0fc15fc-3dd3-4822-848c-76f84585202d',
     'spec': 'DUMMY',
     'root': '/placeholder/path',
     'resource_kwargs': {'a': 1, 'b': 2},
     'resource_path': 'stack.tiff',
     'run_start': '8172473c-fec5-4baf-b28a-73bc4ada3bc5'}

fails with

jsonschema.exceptions.ValidationError: Additional properties are not allowed ('resource_kwargs', 'resource_path', 'root', 'spec', 'uid' were unexpected)

Solution

  • If you're using Draft-2020-12, change this line.

    additionalProperties: false to unevaluatedProperties: false

    allOf and additionaProperties don't really work well together with the way you are trying to use it.

    If you just use a $ref without the allOf, does your generator create two classes?

    {
      "$ref": "#/$defs/PartialResource"
    }