docs: def to_unicode(text, charset=None):
  	"""Convert a `str` object to an `unicode` object.
  
  	If `charset` is given, we simply assume that encoding for the text,
  	but we'll use the "replace" mode so that the decoding will always
  	succeed.
  	If `charset` is ''not'' specified, we'll make some guesses, first
  	trying the UTF-8 encoding, then trying the locale preferred encoding,
  	in "replace" mode. This differs from the `unicode` builtin, which
  	by default uses the locale preferred encoding, in 'strict' mode,
  	and is therefore prompt to raise `UnicodeDecodeError`s.
  
  	Because of the "replace" mode, the original content might be altered.
  	If this is not what is wanted, one could map the original byte content
  	by using an encoding which maps each byte of the input to an unicode
  	character, e.g. by doing `unicode(text, 'iso-8859-1')`.
  	"""
  	if not isinstance(text, str):
  		if isinstance(text, Exception):
  			# two possibilities for storing unicode strings in exception data:
  			try:
  				# custom __str__ method on the exception (e.g. PermissionError)
  				return unicode(text)
  			except UnicodeError:
  				# unicode arguments given to the exception (e.g. parse_date)
  				return ' '.join([to_unicode(arg) for arg in text.args])
  		return unicode(text)
  	if charset:
  		return unicode(text, charset, 'replace')
  	else:
  		try:
  			return unicode(text, 'utf-8')
  		except UnicodeError:
  			return unicode(text, locale.getpreferredencoding(), 'replace')