Eu conheço o esquema% uxxxx não padrão, mas essa não parece uma escolha sábia, pois o esquema foi rejeitado pelo W3C.
Alguns exemplos interessantes:
O personagem do coração. Se eu digitar no meu navegador:
http://www.google.com/search?q=♥
Em seguida, copie e cole, vejo este URL
http://www.google.com/search?q=%E2%99%A5
o que faz parecer que o Firefox (ou Safari) está fazendo isso.
urllib.quote_plus(x.encode("latin-1"))
'%E2%99%A5'
o que faz sentido, exceto para coisas que não podem ser codificadas em Latin-1, como o caractere de ponto triplo.
…
Se eu digitar o URL
http://www.google.com/search?q=…
no meu navegador, copie e cole, eu obtenho
http://www.google.com/search?q=%E2%80%A6
costas. Que parece ser o resultado de fazer
urllib.quote_plus(x.encode("utf-8"))
o que faz sentido, pois ... não pode ser codificado com Latin-1.
Mas não está claro para mim como o navegador sabe se deve decodificar com UTF-8 ou Latin-1.
Uma vez que isso parece ser ambíguo:
In [67]: u"…".encode('utf-8').decode('latin-1')
Out[67]: u'\xc3\xa2\xc2\x80\xc2\xa6'
funciona, então não sei como o navegador descobre se deve decodificar isso com UTF-8 ou Latin-1.
Qual é a coisa certa a fazer com os personagens especiais com os quais preciso lidar?