code: def from_serializable_dict(x):
      
      if "__name__" in x:
          return _lookup_value(x.pop("__module__"), x.pop("__name__"))
  
      non_string_key_objects = [
          from_json(serialized_key)
          for serialized_key
          in x.pop(SERIALIZED_DICTIONARY_KEYS_FIELD, [])
      ]
      converted_dict = type(x)()
      for k, v in x.items():
          serialized_key_index = parse_serialized_keys_index(k)
          if serialized_key_index is not None:
              k = non_string_key_objects[serialized_key_index]
  
          converted_dict[k] = from_serializable_repr(v)
      if "__class__" in converted_dict:
          class_object = converted_dict.pop("__class__")
          if "__value__" in converted_dict:
              return class_object(converted_dict["__value__"])
          elif hasattr(class_object, "from_dict"):
              return class_object.from_dict(converted_dict)
          else:
              return class_object(**converted_dict)
      return converted_dict
docs: Reconstruct a dictionary by recursively reconstructing all its keys and
      values.
  
      This is the most hackish part since we rely on key names such as
      __name__, __class__, __module__ as metadata about how to reconstruct
      an object.
  
      TODO: It would be cleaner to always wrap each object in a layer of type
      metadata and then have an inner dictionary which represents the flattened
      result of to_dict() for user-defined objects.