code: def to_dict_hook(obj):
      
      if hasattr(obj, 'to_dict'):
          result = obj.to_dict()
          assert isinstance(result, dict), 'to_dict must return a dictionary'
          result['_type'] = f'{obj.__module__}.{obj.__class__.__name__}'
          result['_version'] = 0
          return result
  
      raise TypeError(
          f'Object of type {obj.__class__.__name__} is not JSON serializable',
      )
docs: Convert internal objects to a serializable representation.
  
      During serialization if the object has the hook method `to_dict` it will be
      automatically called and metadata for decoding will be added. This allows
      for the translation of objects trees of arbitrary depth. E.g.:
  
      >>> class Root:
      >>>     def __init__(self, left, right):
      >>>         self.left = left
      >>>         self.right = right
      >>>     def to_dict(self):
      >>>         return {
      >>>           'left': left,
      >>>           'right': right,
      >>>         }
      >>> class Node:
      >>>     def to_dict(self):
      >>>         return {'value': 'node'}
      >>> root = Root(left=None(), right=None())
      >>> json.dumps(root, default=to_dict_hook)
      '{
          "_type": "Root",
          "left": {"_type": "Node", "value": "node"},
          "right": {"_type": "Node", "value": "node"}
      }'