alecthomas / voluptuous

CONTRIBUTIONS ONLY: Voluptuous, despite the name, is a Python data validation library.
https://pypi.org/project/voluptuous
BSD 3-Clause "New" or "Revised" License
1.82k stars 218 forks source link

If this then that scenario #393

Closed RobCoops closed 5 years ago

RobCoops commented 5 years ago

I have the following valid data sets: {'a': , 'd':} {'a': {'b': 'String 1'}, 'd':} {'a': {'b': 'String 1', 'c': 'String 2'}, 'd':} Invalid would be for instance: {'a': {'c': 'String 2'}, 'd':}

Basically only if key 'b' exists is key 'c' allowed. it cannot exist on its own as a child of 'a' To test this I created the following bit of code:

from voluptuous import Schema, Any, Optional, All, ALLOW_EXTRA

simple = Schema({'a': None}, required=True)
complex = Schema({'a': {'b': str, Optional('c'): str}}, required=True)
main = Schema({'d': None}, extra=ALLOW_EXTRA)

demo = {'a': {'b': 'String 1', 'c': 'String 2'}}
test_1 = Any(simple, complex)
print( test_1(demo) )

test_2 = All(main, Any(simple, complex))
print( test_2(demo) )

This works perfectly fine with the exception that now I can in my main schema add any number of arbitrary keys which is not desirable. As the main schema is rather complex and large I would very much like to avoid a scenario where I replicate the same schema multiple times for each of these it key 'b' exists then key 'c' can exist otherwise it should not be there type scenario's as that would very quickly balloon out of all reasonable proportion. Yet I need to be strict on my main schema and not allow extra keys. Is this a bug (needing the EXTRA_KEYS option enabled to be able to handle such scenario's or is this as designed and am I overlooking an obvious solution to this (what at least in my mind) common scenario?

svisser commented 5 years ago

I haven't checked every case but it seems something like this should work:

from voluptuous import *

s = Schema({
  Required('a'): Maybe({
    Required('b'): str,
    Optional('c'): str,
  }),
  Optional('d'): None,
})
RobCoops commented 5 years ago

Thank you this is exactly what I was looking for.