Rastreando conversões unicode implícitas no Python 2
Eu tenho um grande projeto em que, em vários lugares, conversões implícitas (coesões) implícitas problemáticas foram usadas na forma de, por exemplo:
someDynamicStr = "bar" # could come from various sources
# works
u"foo" + someDynamicStr
u"foo{}".format(someDynamicStr)
someDynamicStr = "\xff" # uh-oh
# raises UnicodeDecodeError
u"foo" + someDynamicStr
u"foo{}".format(someDynamicStr)
(Possivelmente outras formas também.)
Agora eu gostaria de rastrear esses usos, especialmente aqueles no código usado ativamente.
Seria ótimo se eu pudesse substituir facilmente ounicode
construtor com um wrapper que verifica se a entrada é do tipostr
e aencoding
/errors
Os parâmetros são definidos com os valores padrão e depois me notificam (imprime o retorno ou algo assim).
/editar:
Embora não esteja diretamente relacionado ao que estou procurando, deparei-me com esse hack gloriosamente horrível de como fazer com que a exceção de decodificação desapareça completamente (a única de decodificação, ou seja,str
paraunicode
, mas não o contrário, consultehttps://mail.python.org/pipermail/python-list/2012-July/627506.html)
Não pretendo usá-lo, mas pode ser interessante para aqueles que enfrentam problemas com entrada Unicode inválida e procuram uma solução rápida (mas pense nos efeitos colaterais):
import codecs
codecs.register_error("strict", codecs.ignore_errors)
codecs.register_error("strict", lambda x: (u"", x.end)) # alternatively
(Uma pesquisa na Internet porcodecs.register_error("strict"
revelou que, aparentemente, é usado em alguns projetos reais.)
/ editar # 2:
Para conversões explícitas, fiz um snippet com a ajuda deuma postagem sobre monkeypatching:
class PatchedUnicode(unicode):
def __init__(self, obj=None, encoding=None, *args, **kwargs):
if encoding in (None, "ascii", "646", "us-ascii"):
print("Problematic unicode() usage detected!")
super(PatchedUnicode, self).__init__(obj, encoding, *args, **kwargs)
import __builtin__
__builtin__.unicode = PatchedUnicode
Isso afeta apenas conversões explícitas usando ounicode()
construtor diretamente, então não é algo que eu preciso.
/ editar # 3:
O segmento "Método de extensão para tipos internos de python!"me faz pensar que, na verdade, pode não ser facilmente possível (pelo menos no CPython).
/ editar # 4:
É bom ver muitas boas respostas aqui, pena que só posso dar a recompensa uma vez.
Nesse meio tempo, me deparei com uma pergunta um pouco semelhante, pelo menos no que a pessoa tentou alcançar:Posso desativar as conversões unicode implícitas do Python para encontrar meus erros de strings mistos? Observe que lançar uma exceção serianão estiveram bem no meu caso. Aqui, eu estava procurando por algo que pudesse me indicar os diferentes locais de código problemático (por exemplo, imprimindo smth.), Mas não algo que pudesse sair do programa ou alterar seu comportamento (porque dessa maneira eu posso priorizar o que corrigir).
Em outra nota, as pessoas que trabalham no projeto Mypy (que incluem Guido van Rossum) também podem apresentar algo semelhante útil no futuro, consulte as discussões emhttps://github.com/python/mypy/issues/1141 e mais recentementehttps://github.com/python/typing/issues/208.
/ editar # 5
Também deparei com o seguinte, mas ainda não tive tempo para testá-lo:https://pypi.python.org/pypi/unicode-nazi