schema icon indicating copy to clipboard operation
schema copied to clipboard

Weird validation error message with inner dictionary

Open asteinlein opened this issue 11 years ago • 4 comments

I might very well be misunderstanding something, but I don't get why the following doesn't work:

import json
from schema import Schema, And, Use
schema = Schema({
    'session_type': And(len, Use(str.lower), lambda s: s in ('newsletter',)),
    'user_ip': And(len, str),
    'options': {
        'skip_recipients_step': bool
    }
})
schema.validate(json.loads("""
{
  "session_type": "newsletter",
  "user_ip": "127.0.0.1",
  "options": {
    "skip_foo_bar": true,
    "skip_recipients_step": true
  }
}
"""
))

This gives these errors:

schema.SchemaError: key 'options' is required
key 'skip_recipients_step' is required

Just validating options with And(dict, len) works just fine, so the key is obviously there. But how can validate the contents of the nested dictionaries?

asteinlein avatar Mar 27 '14 17:03 asteinlein

Sorry, the error message is misleading. There are two problems with that schema:

  1. options hash is missing a skip_foo_bar key. You need to either include it, or something like Optional(object): object to allow non-specified keys to validate.
  2. You should use unicode instead of str, since json library returns unicode objects. You could also use basestring, which is a superclass, but it might not suite every case, because it is an abstract class without methods.
import json
from schema import Schema, And, Use, Optional
schema = Schema({
    'session_type': And(len, Use(unicode.lower), lambda s: s in ('newsletter',)),
    'user_ip': And(len, unicode),
    'options': {
        'skip_recipients_step': bool,
        Optional(unicode): object,
    }
})
print schema.validate(json.loads("""
{
  "session_type": "newsletter",
  "user_ip": "127.0.0.1",
  "options": {
    "skip_foo_bar": true,
    "skip_recipients_step": true
  }
}
"""))

keleshev avatar Mar 27 '14 19:03 keleshev

Thanks for your quick reply!

Indeed you are right, the issue was really me being side-tracked by that super-confusing error message, hehe. It turns out that any error I trigger within the inner dictionary whatsoever leads to those errors. That threw me off guard. :) I have therefore modified the title of this issue to better reflect the actual bug.

Regarding unicode vs. str, thanks for the suggestion. However I'm running Python 3, so str works just fine. :)

asteinlein avatar Mar 27 '14 21:03 asteinlein

Bad error messages, are number one, if not the only problem with schema. I really wish to sit down and fix it, but can't squeeze any time just yet.

keleshev avatar Mar 28 '14 10:03 keleshev

Running @asteinlein's original example with the current master (e94b7144f3016654d1360eb1c070fd2db0d54a43):

$ python3.4 issue38.py 
Traceback (most recent call last):
  File "issue38.py", line 19, in <module>
    """
  File "/home/simon/src/schema/schema.py", line 130, in validate
    nvalue = Schema(svalue, error=e).validate(value)
  File "/home/simon/src/schema/schema.py", line 153, in validate
    e)
schema.SchemaError: Wrong keys 'skip_foo_bar' in {'skip_recipients_step': True, 'skip_foo_bar': True}

Does this resolve the issue, @asteinlein?

sjakobi avatar Sep 25 '15 23:09 sjakobi