2

I'm trying to use Cerberus in Python to validate some data.
I found out that for 'boolean' type, the validator always return True, like this:

import cerberus
bool_schema = {'name': {'type': 'boolean', 'required': True}}
cerberus.schema_registry.add('bool_schema', bool_schema)

v = cerberus.Validator({'name': {'schema': 'bool_schema'}})
test1 = {'name': 'a'}
test2 = {'name': 0}
print(v.validate(test1))
print(v.validate(test2))

The above code prints two Trues.
Actually, what I need is to validate if the value is True or False (bool type in Python), other values should not pass the validator.

smci
  • 32,567
  • 20
  • 113
  • 146
Hou Lu
  • 3,012
  • 2
  • 16
  • 23
  • What version of `cerberus` are you using? the above code causes an error ("`raise SchemaError(self.schema_validator.errors) cerberus.schema.SchemaError: {'name': [{'schema': [{'anyof': ['no definitions validate', {'anyof definition 1': ['Rules set definition boolean not found.'], 'anyof definition 0': ['Schema definition boolean not found.']}]}]}]}`" with `cerberus` 1.0.1 which is the latest. – DeepSpace Jan 17 '17 at 14:20
  • I installed `cerberus` through `pip` and the `cerberus.__version__` shows it is precisely version 1.0.1 – Hou Lu Jan 17 '17 at 15:09
  • Sorry, I wrote something wrong in the question, the schema name in `Validator` is `'bool_schema'` not `'schema'`. – Hou Lu Jan 17 '17 at 15:11

2 Answers2

3

This is a semantically issue. Though you didn't specify explicitly what you want to achieve, I'm assuming you want to test whether the value mapped to name in a dictionary is a boolean and ensure it is present.

In line 4 of your example code you're defining a schema that refers to a previously defined schema from a schema registry. While validation it will be interpreted as

{'name': 
    {'schema': {
       {'type': 'boolean',
        'required': True}
}}}

The second-level schema rule will only be processed if the value of name is a mapping. In each of your examples this is not the case, which will effectively process no rule at all and thus the validation returns True each time.

In order to answer the question I assumed above, this will cover it:

import cerberus
required_boolean = {'type': 'boolean', 'required': True}
cerberus.rules_set_registry.add('required_boolean', required_boolean)
v = cerberus.Validator({'name': 'required_boolean'})
funky-future
  • 3,716
  • 1
  • 30
  • 43
2

Might be an issue with the schema registry (I opened a ticket so we can investigate it further - will report back here).

In the meantime, you can skip the registry and it will work just fine:

from cerberus import Validator

schema = {'name': {'type': 'boolean', 'required': True}}

v = Validator()
v.validate({'name': 'a'})
False

v.errors
{'name': ['must be of boolean type']}

EDIT for future readers: the answer from @funky-future below actually explains why your code was failing, and how to fix it.

Nicola Iarocci
  • 6,606
  • 1
  • 20
  • 33