cerberus icon indicating copy to clipboard operation
cerberus copied to clipboard

`type` field cause exception

Open b3g00d opened this issue 5 years ago • 5 comments

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.

b3g00d avatar Jun 05 '20 06:06 b3g00d

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.

funkyfuture avatar Jun 05 '20 12:06 funkyfuture

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

b3g00d avatar Jun 06 '20 05:06 b3g00d

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 avatar Jun 14 '20 20:06 funkyfuture

@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.

b3g00d avatar Jun 16 '20 08:06 b3g00d

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.

funkyfuture avatar Sep 28 '20 20:09 funkyfuture