`type` field cause exception
Used Cerberus version / latest commit: 1.3.2
-
[ ] I have the capacity to improve the docs when my problem is solved.
-
[ ] I have the capacity to submit a patch when a bug is identified.
-
[ x] My question does not concern a practical use-case that I can't figure out to solve.
Bug report / Feature request
I have a sample schema:
{'metadata': {'type': 'dict',
'nullable': True,
'schema': {'image_thumb': {'type': 'list',
'required': False,
'default': [],
'minlength': 0,
'maxlength': 10,
'schema': {'type': 'dict',
'default': None,
'nullable': True,
'schema': {'width': {'type': 'integer', 'required': True}}}}}}}
Expected: return image_thumb must be a list
it will return an exception when an object was {'metadata': {'image_thumb': {'type': 'error'}}}
with type in the body.
please provide a unit test that is as sparse as possible to replicate the problem? it would also be helpful if you provided the full traceback of the exception.
Example use-case:
import cerberus
schema = {
"metadata": {
"type": "dict",
"nullable": True,
"schema": {
"image_thumb": {
"type": "list",
"required": False,
"default": [],
"minlength": 0,
"maxlength": 10,
"schema": {
"type": "dict",
"default": None,
"nullable": True,
"schema": {
"width": {"type": "integer", "required": True},
},
},
},
},
}
}
objType2Name = {"metadata": {"image_thumb": {"type2": "error"}}}
objTypeName = {"metadata": {"image_thumb": {"type": "error"}}}
val = cerberus.Validator(schema)
# This will return False as expected
val.validate(objType2Name)
# [Out]# False
#
# This wwill raise Error
val.validate(objTypeName)
Output
Traceback (most recent call last):
File "sample.py", line 32, in <module>
val.validate(objTypeName)
File "/home/begood/.local/share/virtualenvs/api-u0lUFnib/lib/python3.7/site-packages/cerberus/validator.py", line 990, in validate
self.__normalize_mapping(self.document, self.schema)
File "/home/begood/.local/share/virtualenvs/api-u0lUFnib/lib/python3.7/site-packages/cerberus/validator.py", line 671, in __normalize_mapping
self.__normalize_containers(mapping, schema)
File "/home/begood/.local/share/virtualenvs/api-u0lUFnib/lib/python3.7/site-packages/cerberus/validator.py", line 748, in __normalize_containers
self.__normalize_mapping_per_schema(field, mapping, schema)
File "/home/begood/.local/share/virtualenvs/api-u0lUFnib/lib/python3.7/site-packages/cerberus/validator.py", line 812, in __normalize_mapping_per_schema
result_value = validator.normalized(mapping[field], always_return_document=True)
File "/home/begood/.local/share/virtualenvs/api-u0lUFnib/lib/python3.7/site-packages/cerberus/validator.py", line 646, in normalized
self.__normalize_mapping(self.document, self.schema)
File "/home/begood/.local/share/virtualenvs/api-u0lUFnib/lib/python3.7/site-packages/cerberus/validator.py", line 671, in __normalize_mapping
self.__normalize_containers(mapping, schema)
File "/home/begood/.local/share/virtualenvs/api-u0lUFnib/lib/python3.7/site-packages/cerberus/validator.py", line 748, in __normalize_containers
self.__normalize_mapping_per_schema(field, mapping, schema)
File "/home/begood/.local/share/virtualenvs/api-u0lUFnib/lib/python3.7/site-packages/cerberus/validator.py", line 812, in __normalize_mapping_per_schema
result_value = validator.normalized(mapping[field], always_return_document=True)
File "/home/begood/.local/share/virtualenvs/api-u0lUFnib/lib/python3.7/site-packages/cerberus/validator.py", line 646, in normalized
self.__normalize_mapping(self.document, self.schema)
File "/home/begood/.local/share/virtualenvs/api-u0lUFnib/lib/python3.7/site-packages/cerberus/validator.py", line 660, in __normalize_mapping
self.__normalize_rename_fields(mapping, schema)
File "/home/begood/.local/share/virtualenvs/api-u0lUFnib/lib/python3.7/site-packages/cerberus/validator.py", line 864, in __normalize_rename_fields
self._normalize_rename(mapping, schema, field)
File "/home/begood/.local/share/virtualenvs/api-u0lUFnib/lib/python3.7/site-packages/cerberus/validator.py", line 877, in _normalize_rename
if 'rename' in schema[field]:
TypeError: argument of type 'NoneType' is not iterable
that's an interesting edge case:
@mark.parametrize(
("outer_type", "inner_type"), product(("dict", "list"), ("dict", "list"))
)
def test_normalization_of_dict_with_a_field_named_type(
outer_type, inner_type
):
# https://github.com/pyeve/cerberus/issues/545
validator = Validator(
{"document": {"type": outer_type, "schema": {"type": inner_type,},},}
)
# this test seems to only fail when the token "type" is used as key:
validator({"document": {"type": None}})
regardless, you're aware that the image_thumb field would expect a list, are you?
@funkyfuture Yes, I know that but someone will input object with wrong type. And I need Cerberus to return an error instead of an exception.
i haven't gone my step debugging routes through this, but it's quiet certain that it stems from the ambiguity of the schema rule with regards to lists and dicts. if so, i doubt that this is fixable. the next major release would have thrown the ambiguity over board. hence i'm considering this as a no-fix from my side.
if you don't want to try to fix it yourself, consider to first rename the field type and later re-rename it. or just test against a schema where the field is first renamed if you aren't using a normalized result anyway.