code: def serialize(obj, no_dump=False):
      
      # print("Serialize (%s): %s" % (no_dump, obj))
  
      if hasattr(obj, "serialize") and isinstance(obj.serialize, collections.Callable):
          o_dict = {
              '__sys_python_module__': "%s.%s" % (obj.__class__.__module__, obj.__class__.__name__),
              'content': obj.serialize()
          }
  
      elif isinstance(obj, dict):
          o_dict = {}
          for key, value in list(obj.items()):
              o_dict[key] = serialize(value, True)
  
      elif isinstance(obj, (list, set)):
          o_dict = [serialize(item, True) for item in obj]
  
      else:
          o_dict = obj
  
      if no_dump:
          return o_dict
  
      result = None
      try:
          result = json.dumps(o_dict, ensure_ascii=False)
      except MemoryError:
          return {'_error': 'Not enough memory on this computer to correctly manage Alignak '
                            'objects serialization! '
                            'Sorry for this, please log an issue in the project repository.'}
  
      return result
docs: Serialize an object.
  
      Returns a dict containing an `_error` property if a MemoryError happens during the
      object serialization. See #369.
  
      :param obj: the object to serialize
      :type obj: alignak.objects.item.Item | dict | list | str
      :param no_dump: if True return dict, otherwise return a json
      :type no_dump: bool
      :return: dict or json dumps dict with the following structure ::
  
         {'__sys_python_module__': "%s.%s" % (o_cls.__module__, o_cls.__name__)
         'content' : obj.serialize()}
      :rtype: dict | str