You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hello, I encountered an issue when loading data into a class with an Optional ObjectID field.
Environment
Python 3.8.5
jsons 1.6.3
Issue
If a class has a non-optional ObjectID field, jsons works fine.
If a class has an optional ObjectID field, but the field is "None" in the dictionary, jsons also works fine.
However, when loading an ObjectID into an Optional[ObjectID] field, the following error happens:
Traceback (most recent call last):
File "/home/yuri/ex.py", line 25, in<module>
print(jsons.load(data2, TestData))
File "/home/yuri/.pyenv/versions/3.8.5/lib/python3.8/site-packages/jsons/_load_impl.py", line 99, in load
return _do_load(json_obj, deserializer, cls, initial, **kwargs_)
File "/home/yuri/.pyenv/versions/3.8.5/lib/python3.8/site-packages/jsons/_load_impl.py", line 111, in _do_load
result = deserializer(json_obj, cls, **kwargs)
File "/home/yuri/.pyenv/versions/3.8.5/lib/python3.8/site-packages/jsons/deserializers/default_object.py", line 40, in default_object_deserializer
constructor_args = _get_constructor_args(obj, cls, **kwargs)
File "/home/yuri/.pyenv/versions/3.8.5/lib/python3.8/site-packages/jsons/deserializers/default_object.py", line 64, in _get_constructor_args
key, value = _get_value_for_attr(obj=obj,
File "/home/yuri/.pyenv/versions/3.8.5/lib/python3.8/site-packages/jsons/deserializers/default_object.py", line 94, in _get_value_for_attr
result = sig_key, _get_value_from_obj(obj, cls, sig, sig_key,
File "/home/yuri/.pyenv/versions/3.8.5/lib/python3.8/site-packages/jsons/deserializers/default_object.py", line 140, in _get_value_from_obj
value = load(obj[sig_key], cls_, meta_hints=new_hints, **kwargs)
File "/home/yuri/.pyenv/versions/3.8.5/lib/python3.8/site-packages/jsons/_load_impl.py", line 82, in load
cls, meta_hints = _check_and_get_cls_and_meta_hints(
File "/home/yuri/.pyenv/versions/3.8.5/lib/python3.8/site-packages/jsons/_load_impl.py", line 198, in _check_and_get_cls_and_meta_hints
raise DeserializationError(msg, json_obj, cls)
jsons.exceptions.DeserializationError: Invalid type: "bson.objectid.ObjectId", only arguments of the following types are allowed: str, int, float, bool, list, tuple, set, dict, NoneType
Reproducing the Error
Here is an example script where this error is happening:
fromdataclassesimportdataclassfromtypingimportOptionalimportjsonsfrombson.objectidimportObjectId@dataclassclassTestData:
"""Test Data"""non_optional_id: ObjectIdoptional_id: Optional[ObjectId] =Nonedata1= {
"non_optional_id": ObjectId(),
}
data2= {
"non_optional_id": ObjectId(),
"optional_id": ObjectId(),
}
# prints: TestData(non_optional_id=ObjectId('62b1411ddde5c1f9fc9842a1'), optional_id=None)print(jsons.load(data1, TestData))
# jsons.exceptions.DeserializationError: Invalid type: "bson.objectid.ObjectId", only arguments of the following types are allowed: str, int, float, bool, list, tuple, set, dict, NoneTypeprint(jsons.load(data2, TestData))
The text was updated successfully, but these errors were encountered:
yurirocha15
changed the title
Error when loading into a class with an Optional bson.ObjectID
DeserializationError when loading into a class with an Optional bson.ObjectID
Jun 20, 2022
You are trying to load a "half json-serialized" object; a dict that contains objects that are not json-compatible (bson.objectid.ObjectId instances).
I traced down what happened. In non-strict mode, when an object is loaded into a class of which it already is an instance (e.g. load("this is a string", str)), the loading is skipped and that instance is returned instantly. This is what happens with your data1. With data2, it compares the type ObjectId with Optional which are inequal, therefore it is not skipped. Then, before actually trying to deserialize an ObjectId, it stops as ObjectId is not a json value (one of str, int, float, bool, list, tuple, set, dict, NoneType).
Do you really need to load a "half json-serialized" object, or would it be possible in your case to just do the following?
This would be possible in the example I posted but not in my real use case. I am parsing a nested dictionary into nested dataclasses; this optional parameter is in the deeper layers of the dictionary. Therefore, using the root dataclass constructor directly is not an option for me.
Is there any way to solve this using custom serializers/deserializers?
Hello, I encountered an issue when loading data into a class with an Optional ObjectID field.
Environment
Python 3.8.5
jsons 1.6.3
Issue
Reproducing the Error
Here is an example script where this error is happening:
The text was updated successfully, but these errors were encountered: