python refuse de décoder le caractère 㐬 dans un JSON

UnicodeDecodeError

Le problème exposé dans ce sujet a été résolu.

Bonjour à toutes et à tous
J’ai un problème avec le décodage de caractères encodés en UTF-8 dans un JSON.
J’ai l’impression que certains caractères de l’extension A d’UNICODE ne passent pas.
J’utilise Python 3.10.5 (tags/v3.10.5:f377153, Jun 6 2022, 16:14:13) [MSC v.1929 64 bit (AMD64)] on win32

Voici mon code :

import json

with open('graphics.txt') as mon_fichier:
    data = json.load(mon_fichier)

print(data)

Et voici mon fichier "graphics.txt" :

{"character":"㐬","strokes":["1 2 3"]}

dump :
7B 22 63 68 61 72 61 63 74 65 72 22 3A 22 E3 90
AC 22 2C 22 73 74 72 6F 6B 65 73 22 3A 5B 22 31 
20 32 20 33 22 5D 7D 0D 0A 

On voit, à la fin de la première ligne et au début de la deuxième ligne du dump, E3 90 AC.
C’est le caractère 㐬, U+342C encodé en UTF-8 qui pose problème à Python.
(voir : https://www.compart.com/en/unicode/U+342C)

L’exécution, cela donne :

Traceback (most recent call last):
File "D:\essai-graphics.py", line 4, in <module> data = json.load(mon_fichier)
File "C:\Users\toto\AppData\Local\Programs\Python\Python310\lib\json__init__.py", line 293, in load return loads(fp.read(),
File "C:\Users\toto\AppData\Local\Programs\Python\Python310\lib\encodings\cp1252.py", line 23, in decode return codecs.charmap_decode(input,self.errors,decoding_table)[0]
UnicodeDecodeError: 'charmap' codec can’t decode byte 0x90 in position 15: character maps to <undefined>

+0 -0

Salut @etherpin,

Le problème vient du charset utilisé par Python lorsqu’il ouvre ton fichier. Comme tu l’as dit, ton caractère existe bel et bien en UTF-8 mais encore faut-il que Python utilise ce charset en ouvrant ton fichier. Dans ton message d’erreur, on peut voir qu’il parle de cp1252 qui est le charset Windows-1252 et non UTF-8. Donc pour régler ça, tu peux faire open('graphics.txt', encoding='utf-8') et ça devrait fonctionner.

C’est amusant car quand j’ai lancé ton programme sur ma machine (sur WSL), il a fonctionné directement. Donc il semblerait que Linux utilise UTF-8 par défaut mais Windows pas.

+2 -0

Oui, c’est effectivement le cas, et windows est très casse-pieds avec ça. Mais je n’aurais pas juré par avance que Python utiliserait également l’encodage système et pas utf-8 par défaut.

Moté

Avec open(’graphics.txt’, encoding = 'utf-8’), ça marche :magicien:

C’est le piège dans lequel je suis tombé.
J’avais cru comprendre de la doc que l’encodage par défaut de Python 3.x est UTF-8.

Merci à tous

+0 -0

J’avais cru comprendre de la doc que l’encodage par défaut de Python 3.x est UTF-8.

Les str sont UTF8 et l’encodage du code source est UTF8, mais open utilise locale.getencoding par défaut (la documentation d'open est d’ailleurs très claire là-dessus…). Ça veut dire que si un programme manipule des fichiers e.g. exclusivement en UTF8 (ou bien qu’on veut manipuler un fichier dont on connait déjà l’encodage), il faut spécifier l’encodage.

Oui, c’est effectivement le cas, et windows est très casse-pieds avec ça. Mais je n’aurais pas juré par avance que Python utiliserait également l’encodage système et pas utf-8 par défaut.

Pour une fois, c’est pas la faute de Windows, c’est plutôt Python qui a fait le choix un peu curieux d’avoir un comportement par défaut qui dépend effectivement de la plateforme sur laquelle on tourne. Même sous unix, ce comportement par défaut n’est pas nécessairement UTF8, et on peut même le changer avec une bête variable d’environnement. Le résultat, c’est qu’il y a beaucoup de codes Python développés sous des plateformes UTF8 qui ne sont en fait pas portables parce qu’ils reposent sur le comportement par défaut.

+0 -0

Au-delà de ça, je ne sais pas quel outil tu utilises pour développer, mais un bon IDE devrait t’avertir quand tu essaies d’utiliser une lecture de fichier sans préciser explicitement l’encodage.

SpaceFox

Je suis pas d’accord, c’est un cas d’usage tout à fait légitime (par exemple si le programme est seul à manipuler un fichier texte). Je ne vois pas pourquoi ce serait le rôle d’un éditeur de texte que de lever un avertissement pour ça.

C’est un cas d’usage parfois légitime, mais problématique parce que non portable, et souvent non voulu. Pour moi c’est du devoir de tes outils de t’avertir de ce genre de point qui peuvent mener à des comportements imprévus et/ou des subtilités qui ne transparaissent pas immédiatement à la lecture du code. Évidemment ces avertissement ne devraient pas être bloquants. Note que je parle de l’usage d’un IDE et pas d’un éditeur de texte.

C’est typiquement le genre d’avertissement dont j’active le maximum disponibles dans mon IDE, et ça m’a évité beaucoup de bugs et d’erreurs stupides, quel que soit le langage.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte