Conozco el esquema% uxxxx no estándar, pero no parece una elección acertada ya que el esquema ha sido rechazado por el W3C.
Algunos ejemplos interesantes:
El personaje del corazón. Si escribo esto en mi navegador:
http://www.google.com/search?q=♥
Luego cópielo y péguelo, veo esta URL
http://www.google.com/search?q=%E2%99%A5
lo que hace que parezca que Firefox (o Safari) está haciendo esto.
urllib.quote_plus(x.encode("latin-1"))
'%E2%99%A5'
lo cual tiene sentido, excepto para las cosas que no se pueden codificar en Latin-1, como el carácter de punto triple.
…
Si escribo la URL
http://www.google.com/search?q=…
en mi navegador, luego copie y pegue, obtengo
http://www.google.com/search?q=%E2%80%A6
espalda. Que parece ser el resultado de hacer
urllib.quote_plus(x.encode("utf-8"))
lo cual tiene sentido ya que… no se puede codificar con Latin-1.
Pero no me queda claro cómo el navegador sabe si decodificar con UTF-8 o Latin-1.
Dado que esto parece ser ambiguo:
In [67]: u"…".encode('utf-8').decode('latin-1')
Out[67]: u'\xc3\xa2\xc2\x80\xc2\xa6'
funciona, así que no sé cómo el navegador se da cuenta de si decodificar eso con UTF-8 o Latin-1.
¿Qué es lo correcto para hacer con los caracteres especiales con los que debo lidiar?