Captain Farrell
Captain Farrell

Reputation: 91

Voluptuous Exclusive Class

I am using voluptuous 0.9.2 and I have a problem with Exclusive class. I need that if there is none of the keys, it should give an error. However, this is okay for voluptuous. Is this a bug of voluptuous? If not, how I can write a script for that?

In order to clarify my problem, assume we built a schema like that:

schema = Schema({Exclusive('a', 'z'): int, Exclusive('b', 'z'): int, 'c': int}, required=True)

I need one and only one of the keys in exclusion group to be given. But when I test with {'c': 5}, it seems to be valid even though I did not give either a or b. I do not know how to make it works especially for this situation.

Upvotes: 2

Views: 1766

Answers (2)

jcollado
jcollado

Reputation: 40394

A trick that works here is to use two different schemas that need to validate at the same time:

from voluptuous import All, Any, Exclusive, Required                                                                                                                         

schema = All(                                                                                                                                                                
    {                                                                                                                                                                        
        Exclusive('a', 'z'): int,                                                                                                                                            
        Exclusive('b', 'z'): int,                                                                                                                                            
        Required('c'): int,                                                                                                                                                  
    },                                                                                                                                                                       
    {                                                                                                                                                                        
        Required(Any('a', 'b')): int,                                                                                                                                        
        Required('c'): int,                                                                                                                                                  
    },                                                                                                                                                                       
)

The first schema fails to validate when both a and b are present and the second schema fails when neither a nor b are present. Hence, either a or b need to be present.

Upvotes: 1

Alex Mitrevski
Alex Mitrevski

Reputation: 223

According to the documentation, Exclusive inherits from Optional, which means that a and b are optional in your schema; that's why {'c': 5} is a valid input. To get around this problem, you need to explicitly specify them as required:

from voluptuous import Schema, Exclusive, Required
schema = Schema({Required(Exclusive('a', 'z')): int, Required(Exclusive('b', 'z')): int, 'c': int}, required=True)

Upvotes: 1

Related Questions