Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Windows, subprocess.Popen & encodage

3 réponses
Avatar
Méta-MCI
Bonjour !


Depuis longtemps, j'avais, occasionnellement, quelques problèmes avec les
chaînes retournées (sous windows), par subprocess.Popen + stdout.read()

La nuit dernière, j'ai (peut-être) trouvé un truc intéressant, à savoir
tester si le second octet est à zéro.

Avec un code de ce genre :

p=subprocess.Popen(u850("cmd /u/c ....
tdata=p.stdout.read()
if ord(tdata[1])==0:
data=tdata.decode('utf-16')
else:
data=tdata.decode('cp850')


ça a l'air de fonctionner. J'ai testé avec :
- des DIR ordinaires
- des DIR sur des répertoires contenant des fichiers avec un nom en
Unicode (cyrillique)
- PING
- quelques commandes diverses


Malheureusement, je n'ai pas trouvé de confirmation, dans aucune doc, ni sur
Internet.


Quelqu'un pourrait-il confirmer ? Me suis-je trompé ? Ai-je trouvé un
vrai truc ?


*désolé pour mon français ordinaire* (ça c'est pour les lecteurs
multi-newsgroups)


@-salutations

Michel Claveau

3 réponses

Avatar
Olivier Ravard
Méta-MCI wrote:

Avec un code de ce genre :

p=subprocess.Popen(u850("cmd /u/c ....
tdata=p.stdout.read()
if ord(tdata[1])==0:


Ne serait-ce pas ceci que tu souhaiterais faire ? :

if tdata[:2]==codecs.BOM_UTF16:
data=tdata.decode('utf-16')
else:
...

data=tdata.decode('utf-16')
else:
data=tdata.decode('cp850')



Avatar
MCI, Shadok Gouroudoudou
Salut !


if tdata[:2]==codecs.BOM_UTF16:


Bon, pas vraiment. Le BOM est (devrait être) utilisé en début des
fichiers XML, mais rien n'est spécifié pour les chaînes.

D'ailleurs codecs.BOM_UTF16 commence par 255 254 ; alors qu'une chaîne
utf-16 retournée par windows retourne 32 0


D'une manière générale, il est très difficile, voire impossible,
d'identifier l'encodage d'une chaîne. Il faut gérer (maîtriser)
soi-même l'encodage utilisé.
Or, dans le cas de subprocess.Popen, c'est un élément extérieur qui
fournit la chaîne. Il faudrait donc obtenir l'information de cet
élément. Quand c'est possible.

Une particularité de l'invite de commande (de windows), c'est qu'elle
peut faire fonctionner une variété énorme de logiciels.

Je me suis donc rabattu sur les cas les plus courants. A savoir que
l'on obtient généralement de l' : cp850 cp1252 cp437 ; et, s'il y a
utilisation d'Unicode (par exemple dans les noms de fichiers), utf-16

Pour utf-16, il y a, heureusement, ce fameux début avec le second octet
à 0

Pour le reste, comme je n'ai aucun moyen de distinguer cp850 de cp1252,
j'ai opté pour le plus courant : cp850








--
@-salutations

Michel Claveau

Avatar
NicolasP

p=subprocess.Popen(u850("cmd /u/c ....
tdata=p.stdout.read()
if ord(tdata[1])==0:
data=tdata.decode('utf-16')
else:
data=tdata.decode('cp850')


ça a l'air de fonctionner. J'ai testé avec :
- des DIR ordinaires
- des DIR sur des répertoires contenant des fichiers avec un nom en
Unicode (cyrillique)
- PING
- quelques commandes diverses


Malheureusement, je n'ai pas trouvé de confirmation, dans aucune doc, ni
sur Internet.


Quelqu'un pourrait-il confirmer ? Me suis-je trompé ? Ai-je trouvé un
vrai truc ?



Et si le premier caractère retourné n'est pas dans la table ascii de base (un caractère accentué par exemple), ça marche aussi ?
En UTF16, les caractères sont codés sur 2 octets. Tous les caractères de la table ascci de base sont codés avec le deuxième octet = 0. Pour les autres, ça dépend de leur indice dans la table unicode.

Nicolas