Heiko Finzel Heiko Finzel - 4 months ago 8
Python Question

How to ensure only patternProperties that match a particular pattern

I'm using python module validictory to validate dicts / yaml configs.

Given the following schema I want to match any count of keys that match "^[0-9x]{3}$" and validate the value with another pattern.

SCHEMA = {
"type": "object",
"patternProperties": {
"^[0-9x]{3}$": {
"type": "string",
"pattern": "^somepattern$"
}
}
}


This works so far but what I want now is:

SCHEMA = {
"type": "object",
"additionalProperties": False,
"patternProperties": {
"^[0-9x]{3}$": {
"type": "string",
"pattern": "^somePattern$"
}
}
}


This doesn't work as I would expect, it seems if additionalProperties is present patternProperties is not evaluated resulting in an error that no keys are allowed that aren't specified in properties.

So how could I ensure that every key in the config follows that exact pattern ("^[0-9x]{3}$")?

Example configs:

{
'5xx': 'someValidValue',
'x9x': 'someValidValue'
}


-> should test True

{
'5xx': 'someValidValue',
'foobar': 'someValidValue', #this one should fail
'baz': 'someValidValue', #this one, too
'x9x1': 'someValidValue', #this one, too
'x9x': 'someValidValue'
}


-> should test False

I tried to "define own type" like documentation says, by giving a pattern within the type block:

...
"type": { "pattern": "^[0-9x]{3}$" }
...


But then it actually tests the values against that pattern, so either I did it wrong or got the documentation wrong (or both).

Note: I have (and want) to use validictory since it is a set module for some 3rd party libs I'm using.

Answer

I can't reproduce your issue. This code works as expected for me (Python 3.5.1, validictory 1.0.2), unless I'm misunderstanding your question?

import validictory

should_work = {
    '5xx': 'someValidValue',
    'x9x': 'someValidValue'
}

should_not_work = {
    '5xx': 'someValidValue',
    'foobar': 'someValidValue', #this one should fail
    'baz': 'someValidValue',    #this one, too
    'x9x1': 'someValidValue',   #this one, too
    'x9x': 'someValidValue'
}

SCHEMA = {
    "type": "object",
    "additionalProperties": False,
    "patternProperties": {
        "^[0-9x]{3}$": {
            "type": "string",
            "pattern": "^someValidValue$"
        },
    },
}

validictory.validate(should_work, SCHEMA) # no exception

validictory.validate(should_not_work, SCHEMA)
# validictory.validator.FieldValidationError ... contains additional property 'baz' not defined by 'properties' or 'patternProperties' and additionalProperties  is False