jsonschema icon indicating copy to clipboard operation
jsonschema copied to clipboard

ErrorTree assumes one error per validator

Open Julian opened this issue 7 years ago • 4 comments

This seems like a correct assumption (both at the minute and likely forever, which probably should be better documented) but if it ever were not the case, it'd silently not do nice things, which is not very nice.

EDIT: it's not the case

Julian avatar Aug 03 '18 22:08 Julian

I think I ran into this today with this.

schema = {
    "type": "object",
    "properties": {
        "accounts": {
            "type": "array",
            "minItems": 1,
            "items": {"$ref": "#/components/schemas/Account"}
        }
    },
    "components": {
        "schemas": {
            "Account": {
                "properties": {
                    "first_name": {"type": "string"},
                    "last_name": {"type": "string"}
                },
                "required": ["first_name", "last_name"]
            }
        }
    },
}

v = Draft7Validator(schema)
item = {"accounts": [{"foo": 123, "bar": True}]}

l = [err for err in v.iter_errors(item)]
error_tree = ErrorTree(v.iter_errors(item))

# prints 2 - first_name and last_name are missing
print(len(l))

# print 1 - the last ValidationError object to be assigned at the level accounts,0 wins.
print(error_tree.total_errors)

this happens because when creating the error tree container, the path deque('accounts', 0) will happen twice in my case both for the required validator and the last one in will get its error assigned. https://github.com/Julian/jsonschema/blob/14710c64f2df383e00366b2db839f40ae0d691c8/jsonschema/exceptions.py#L217-L223

Would checking to see if an error already exists at the level and appending another ValidationError object be possible?

ThrowsException avatar Apr 01 '19 20:04 ThrowsException

@Julian Any updates on this issue?

I have this schema and instance:

schema = {
    "title": "title",
    "type": "object",
    "additionalProperties": False,
    "properties": {
        "date_filter": {
            "type": "object",
            "additionalProperties": False,
            "properties": {
                "from": {
                    "type": "string",
                    "format": "date-time"
                },
                "to": {
                    "type": ["string", "null"],
                    "format": "date-time"
                }
            },
            "required": ["from", "to"]
        }
    }
}

instance = {
    "date_filter": {},
    "test_field": 1
}

The ValidationError for "from" is missing.

TheFirstMe avatar Aug 09 '21 15:08 TheFirstMe

Not if the ticket is still open, but I'm more than happy to review a proposed change (or design)!

Julian avatar Aug 09 '21 16:08 Julian

The stdlib’s email.message.EmailMessage class works like a dict but has a .get_all(key) method.

If you use a similar multidict class to back ErrorTree, you can also make .items() and .values() yield multiple errors for the same key.

flying-sheep avatar Oct 25 '22 11:10 flying-sheep