Forum Programmation.python Python et l'unicode

Posté par  (site web personnel) . Licence CC By‑SA.
Étiquettes : aucune
1
8
mar.
2015

Bonjour,

j'ai des gens qui me rapportent des bugs de ce type:

UnicodeEncodeError: 'utf-8' codec can't encode character '\udcc0' in position 76: surrogates not allowed

Ce sont des fichiers dont le nom est codé en iso8859-15 sur un OS en UTF-8…

Mais je ne vois pas comment m'en sortir :-( Quelqu'un a déjà eu à faire à ce problème?

  • # deux possibilités

    Posté par  . Évalué à 2.

    solution simple

    Ce sont des fichiers dont le nom est codé en iso8859-15 sur un OS en UTF-8…

    en renommant le fichier en UTF-8
    en meme temps utiliser des caracteres speciaux dans les noms de fichier, c'est pas cool quand meme

    car comme tu le vois ici, c'est dependant du filesystem

    solution plus complexe

    revoir ton code pour que si l'erreur se presente tu refasses une tentative en ISO8859-1

  • # Encodages…

    Posté par  (site web personnel) . Évalué à 3. Dernière modification le 08 mars 2015 à 22:19.

    En fait, c'est pas un problème spécifique de python ou d'un quelconque langage : avec les encodages il n'y a pas de solution miracle, il faut toujours penser à qu'est-ce qu'on manipule en entrée, sortie, et entre-temps.

    Je connais pas trop python, mais il me semble que dans le version 2.* par défaut tout était traité comme du binaire par défaut, et dans les versions récentes de 3.* c'est l'encodage de la locale qui est utilisé (par exemple pour open()), ce qui est un peu un piège, car ça fera souvent ce que tu veux, mais pas toujours.

    Dans ton cas, comme dit NeoX, si tu ne peux pas prévoir l'encodage des fichiers (c'est pas les tiens, par exemple), tu dois faire un decode manuel de tes noms de fichiers après les avoir récupéré en mode binaire par exemple, ou bien en précisant un encodage sur le filehandle au moment où tu les récupères. Si tu ne sais pas à l'avance l'encodage, faudra utiliser un module avec des fonctions pour essayer de deviner l'encodage, voire juste essayer des decode manuellement et si ça lance une exception en essayer un autre, tout en sachant que c'est jamais totalement fiable (il n'y a que l'utilisateur qui peut vraiment connaître l'encodage de ses fichiers).

    Si à aucun moment tu ne mélanges ces noms de fichiers avec une autre chaîne dans un encodage différent, tu peux probablement aussi juste les traiter comme du binaire tout du long, il y a des chances que ce soit suffisant, faut juste pas faire la bêtise de mélanger une telle chaîne avec une autre chaîne qui n'a peut-être pas le même encodage.

  • # règles numéro 4 et 5 en particulier

    Posté par  (site web personnel) . Évalué à 6.

    • [^] # Re: règles numéro 4 et 5 en particulier

      Posté par  (site web personnel) . Évalué à 3.

      Je veux bien moi mais si je fais string.decode('utf-8') sur une chaine contenant de l'iso, ça plante avec l'erreur mentionnée dans mon post…

      • [^] # Re: règles numéro 4 et 5 en particulier

        Posté par  . Évalué à 1.

        Si ta chaîne est en iso, il faut que tu fasses string.decode('isoxxx')

      • [^] # Re: règles numéro 4 et 5 en particulier

        Posté par  (site web personnel) . Évalué à 3.

        le lien suivant traite des surrogate

        http://lucumr.pocoo.org/2013/7/2/the-updated-guide-to-unicode/

        extrait

        These functions might be useful:
        
        def remove_surrogate_escaping(s, method='ignore'):
            assert method in ('ignore', 'replace'), 'invalid removal method'
            return s.encode('utf-8', method).decode('utf-8')
        
        def is_surrogate_escaped(s):
            try:
                s.encode('utf-8')
            except UnicodeEncodeError as e:
                if e.reason == 'surrogates not allowed':
                    return True
                raise
            return False```
        

        ウィズコロナ

      • [^] # Re: règles numéro 4 et 5 en particulier

        Posté par  . Évalué à 3.

        Il y a des libs python qui existe pour tenter de déterminer le codage des string. Je ce conseille de tenter l'utf8 avec un try, si ça foire tu utilisé la lib pour connaître l'encodage et tuconverti avec ça. Ça devrait éviter les exceptions mais tu pourrais avoir du cp1252 au lieu de l'iso8815 dans la détection.

        « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

  • # Problème résolu !

    Posté par  . Évalué à 0.

    Et tu as fait exactement ce qu'il fallait faire, je pense.

    Pour un sextumvirat ! Zenitram, Tanguy Ortolo, Maclag, xaccrocheur, arnaudus et alenvers présidents !

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.