Description
Describe the bug
If a data structure contains a None value the serialize/deserialize roundtrip breaks
To Reproduce
Delta(Delta(DeepDiff({"a":None}, {"a":1})).dumps())
deepdiff.serialization.ForbiddenModule: Module 'builtins.type' is forbidden. You need to explicitly pass it by passing a safe_to_import parameter
Although there is builtins.None
in SAFE_TO_IMPORT
, pickle need to use builtin.type for reason I did not figure yet
This works :
Delta(Delta(DeepDiff({"a":None}, {"a":1})).dumps(), safe_to_import={'builtins.type'})
=>
<Delta: {'type_changes': {"root['a']": {'old_type': <class 'NoneType'>, 'new_type': <class 'int'>, 'new_v...}
But of course allowing builtins.type
opens the insecure floodgates wide open, since any class can then be instanciated.
Expected behavior
Delta(Delta(DeepDiff({"a":None}, {"a":1}), safe_to_import={'builtins.type'}).dumps())
=>
<Delta: {'type_changes': {"root['a']": {'old_type': <class 'NoneType'>, 'new_type': <class 'int'>, 'new_v...}
OS, DeepDiff version and Python version (please complete the following information):
- OS: [Manjaro]
- Version [rolling]
- Python: 3.9.1
Additional context
Deepdiff and delta are amazing ;)
Side note : the documentations at https://zepworks.com/deepdiff/5.0.0/delta.html#delta-safe-to-import-label seems incorrect
delta = Delta(t1, t2, safe_to_import={'mypackage.mymodule'})
implies that the safe_to_import parameter acts at Delta creation time (and it looks like DeepDiff syntax) and it is not.
It acts (and that's logical) at de-serialization time :
delta = Delta(delat_dumps, safe_to_import={'mypackage.mymodule'})
Maybe Delta init does a little too much magic, Delta.from_diff() and Delta.unserialize() or other explicit classmethod whould make use more "intuitive".