New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unexpected TypeError when using allow_unknown in a schema defining a list of dicts #250

Closed
daviskirk opened this Issue Jul 26, 2016 · 5 comments

Comments

Projects
None yet
3 participants
@daviskirk
Copy link
Contributor

daviskirk commented Jul 26, 2016

I'm not sure if I understand the 'allow_unknown' rule correctly:

I can do this

import cerberus
schema = {
    'test': {
        'schema': {'a': {'type': 'string'}}, 'type': 'dict', 'allow_unknown':True
    }
}

validator = cerberus.Validator(schema)
validator.validate({'test': {'unknown_key': 'unknown_value'}})
validator.validate({'test': {}})

and both validations return True.

But if I nest the dictionary inside a list and try to do the same:

schema = {
    'test': {
        'type': 'list',
        'schema': {
            'type': 'dict',
            'allow_unknown':True,
            'schema': {'a': {'type': 'string'}}
        }
    }
}
validator = cerberus.Validator(schema)
validator.validate({'test': [{'unknown_key': 'unknown_value'}]})
validator.validate({'test': {}})

unexpected things (for me at least) happen.
The first validation results in True as expected. For the second however, I would have expected it to return False and indicate an error (because of the dict was used instead of the list) within the errors attribute. Instead, cerberus throws a TypeError while calling getitem on the schema using the 'allow_unknownvalueTrue` which of course fails.

Am I using the rule incorrectly? I am using cerberus 1.0rc0 pulled directly from github.

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-44-bead38c40317> in <module>()
----> 1 validator.validate({'test': {}})

/pythonenv/lib/python3.5/site-packages/cerberus/validator.py in validate(self, document, schema, update, normalize)
    730         if normalize:
    731             self.__normalize_mapping(self.document, self.schema)
--> 732 
    733         for field in self.document:
    734             if self.ignore_none_values and self.document[field] is None:

/pythonenv/lib/python3.5/site-packages/cerberus/validator.py in __normalize_mapping(self, mapping, schema)
    497         self.__normalize_default_fields(mapping, schema)
    498         self._normalize_coerce(mapping, schema)
--> 499         self.__normalize_containers(mapping, schema)
    500         return mapping
    501 

/pythonenv/lib/python3.5/site-packages/cerberus/validator.py in __normalize_containers(self, mapping, schema)
    552                 if set(schema[field]) & set(('allow_unknown', 'purge_unknown',
    553                                              'schema')):
--> 554                     self.__normalize_mapping_per_schema(field, mapping, schema)
    555             elif isinstance(mapping[field], _str_type):
    556                 continue

/pythonenv/lib/python3.5/site-packages/cerberus/validator.py in __normalize_mapping_per_schema(self, field, mapping, schema)
    600             purge_unknown=schema[field].get('purge_unknown', self.purge_unknown))  # noqa
    601         mapping[field] = validator.normalized(mapping[field],
--> 602                                               always_return_document=True)
    603         if validator._errors:
    604             self._error(validator._errors)

/pythonenv/lib/python3.5/site-packages/cerberus/validator.py in normalized(self, document, schema, always_return_document)
    484         """
    485         self.__init_processing(document, schema)
--> 486         self.__normalize_mapping(self.document, self.schema)
    487         self.error_handler.end(self)
    488         if self._errors and not always_return_document:

/pythonenv/lib/python3.5/site-packages/cerberus/validator.py in __normalize_mapping(self, mapping, schema)
    495         if self.purge_unknown:
    496             self._normalize_purge_unknown(mapping, schema)
--> 497         self.__normalize_default_fields(mapping, schema)
    498         self._normalize_coerce(mapping, schema)
    499         self.__normalize_containers(mapping, schema)

/pythonenv/lib/python3.5/site-packages/cerberus/validator.py in __normalize_default_fields(self, mapping, schema)
    665 
    666         for field in [x for x in fields if 'default' in schema[x]]:
--> 667             self._normalize_default(mapping, schema, field)
    668 
    669         known_fields_states = set()

/pythonenv/lib/python3.5/site-packages/cerberus/validator.py in <listcomp>(.0)
    665 
    666         for field in [x for x in fields if 'default' in schema[x]]:
--> 667             self._normalize_default(mapping, schema, field)
    668 
    669         known_fields_states = set()

TypeError: argument of type 'bool' is not iterable

@daviskirk daviskirk changed the title allow_unknown in list of dicts unexpected exception when using allow_unknown in a schema defining a list of dicts Jul 26, 2016

@daviskirk daviskirk changed the title unexpected exception when using allow_unknown in a schema defining a list of dicts unexpected TypeError when using allow_unknown in a schema defining a list of dicts Jul 26, 2016

@daviskirk daviskirk changed the title unexpected TypeError when using allow_unknown in a schema defining a list of dicts Unexpected TypeError when using allow_unknown in a schema defining a list of dicts Jul 26, 2016

@funkyfuture

This comment has been minimized.

Copy link
Member

funkyfuture commented Jul 26, 2016

your intended usage looks reasonable to me.

what puzzles me is that this code is actually reached, as there is no field in the document at all.

@nicolaiarocci

This comment has been minimized.

Copy link
Member

nicolaiarocci commented Jul 27, 2016

At quick glance I'd say this is likely to be a bug. Thanks.

@nicolaiarocci

This comment has been minimized.

Copy link
Member

nicolaiarocci commented Aug 24, 2016

@funkyfuture do you have time to look at this? I would like to release 1.0 by the end of the month/first days of september at the latest, before PyConUK. We can postpone this to 1.x eventually.

@funkyfuture

This comment has been minimized.

Copy link
Member

funkyfuture commented Aug 24, 2016

hm, i have a lot spinning atm. and currently we got something that deserves to be called summer here, eventually. so, can't make no promises.

@daviskirk have you looked into it?

@daviskirk

This comment has been minimized.

Copy link
Contributor

daviskirk commented Aug 25, 2016

Haven't yet looked into this, but I might have time to poke around and see if it's an easy fix... I've been putting it off but my workarounds are becoming ugly enough that I shouldn't... I'll have a look this weekend

daviskirk added a commit to daviskirk/cerberus that referenced this issue Aug 26, 2016

@daviskirk daviskirk referenced this issue Aug 26, 2016

Closed

Fixes #251 #256

funkyfuture added a commit to funkyfuture/cerberus that referenced this issue Oct 26, 2016

funkyfuture added a commit to funkyfuture/cerberus that referenced this issue Oct 26, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment