jpmckinney / validictory

🎓 deprecated general purpose python data validator
Other
240 stars 57 forks source link

Dont reuse pointers to default dict or lists #112

Closed NickStefan closed 7 years ago

NickStefan commented 7 years ago

When using an array or an object as a default value:

        schema = {
            "type": "object",
            "properties": {
                "foo": {
                    "default": []
                }
            }
        }

The pointer to the array *in the schema** is reused as the pointer to the object that gets validated and applied with a default! This leads to really odd bugs where each time you validate an object, the array from the previous validation may be getting reused!

Continuing with the schema above, I wrote a failing test, using the id method:

        data = {}

        validictory.validate(
            data,
            schema,
            required_by_default=True,
            apply_default_to_data=True
        )

        # correctly apply default
        self.assertEqual({"foo":[]}, data)

        # dont re-use the actual array from the schema
        applied_default_id = id(data["foo"])
        original_schema_id = id(schema["properties"]["foo"]["default"])

        self.assertNotEqual(applied_default_id, original_schema_id)

In order to get this test passing, we deep clone any defaults that are of instance dict or list.

Please let me know if there's anything I need to do to get this merged! Thanks

coveralls commented 7 years ago

Coverage Status

Coverage increased (+0.04%) to 96.496% when pulling 520c5fa63de8b624324cc4be1312ab91a6e8987d on NickStefan:dont-reuse-defaults into 65cc657d9ff6479b18de0f30eda1d4afaa60d87a on jamesturk:master.

NickStefan commented 7 years ago

@tnm

jamesturk commented 7 years ago

this looks pretty good 👍 nice catch

NickStefan commented 7 years ago

Thanks @jamesturk. any chance you could cut a new release on pypi?

jamesturk commented 7 years ago

absolutely