LINUX.ORG.RU

[пистон 3][какого хера] fd.read(): UnicodeDecodeError: 'utf8' codec can't decode byte


0

1

Здравствуйте мои дорогие любители питона. Кажется я начинаю понимать тех людей которые сидят на втором питоне. Вот этот код отлично работает в py2, но выдаёт какую-то хрень в py3k:

import os
cmd = "streamer -s 640x480 -q -f jpeg -o /dev/stdout"
fd = os.popen(cmd)
print(fd.read())

Я сначала всё через subprocess делал, там оно так же падало. Даже багрепорт по этому поводу нашёл. Решил юзать более низкоуровневые средства. Внезапно оказалось что даже file прогоняется через BufferedIncrementalDecoder.

Что делать, кто виноват и как дальше жыть?

★★★★★

use Perl, Luke!

anonymous
()

Workaround.

import os
cmd = "streamer -s 640x480 -q -f jpeg -o /dev/stdout"
fd = os.popen(cmd)
data = fd._stream.buffer.read()
print(data)

P.S. Не буду юзать тройку еще года два.

baverman ★★★
()

Я сначала всё через subprocess делал, там оно так же падало

Кстати, УМВР.

import os
import subprocess

p = subprocess.Popen("streamer -s 640x480 -q -f jpeg -o /dev/stdout", stdout=subprocess.PIPE, shell=True)
print(p.stdout.read())
baverman ★★★
()
Ответ на: комментарий от anonymous

убивать за такие теги!

предложи свои

true_admin ★★★★★
() автор топика
Ответ на: комментарий от RA

Use Python3.2, Luke!

Да у меня ваще 3.3a0 :). Эти баги висят незакрытыми, так что все версии ей подвержены.

true_admin ★★★★★
() автор топика
Ответ на: комментарий от anonymous

В интернете чего-то пишут про переопределение io.TextIOWrapper.

Как-то слишком сурово. А где пишут? Хочу посмотреть что там делают. Есть подозрение что это может поломать код в неожиданных местах.

true_admin ★★★★★
() автор топика
Ответ на: комментарий от true_admin

Я использовал subprocess.getstatusoutput()

Гм, еще бы оно работало.

subprocess.getstatusoutput(cmd)

Return (status, output) of executing cmd in a shell.

Execute the string cmd in a shell with os.popen() and return a 2-tuple (status, output)
baverman ★★★
()
Ответ на: комментарий от baverman

Фига се, я о _stream даже и не знал. В доках о нём упоминания тоже нет. И open возвращает file object без _stream...

true_admin ★★★★★
() автор топика
Ответ на: комментарий от baverman

И после этого они пишут что os.popen deprecated?? Да ещё и появились эти функции сильно позже чем возник subprocess.

true_admin ★★★★★
() автор топика
Ответ на: комментарий от true_admin

Фига се, я о _stream даже и не знал.

Немедленно про него забудь. Я это по дурости написал, такого рабочего кода никогда в жизни не сделаю, иначе в полночь он может превратиться в тыкву и меня съест дракон.

baverman ★★★
()
Ответ на: комментарий от namezys

хм. странно. не логично как-то

Это не фича, это натуральная бага.

baverman ★★★
()
Ответ на: комментарий от namezys

read обычно bytearray должен возращать

вот и я о том же! Какие тут, нах, преобразования кодировок. Я ф шоке...

true_admin ★★★★★
() автор топика
Ответ на: комментарий от namezys

>ну логика отдыхает
popen предполагает текстовые символы, а они кодируются
может всё же есть разница в открытие файла как текстового и как потока байтов?

anonymous
()
Ответ на: комментарий от anonymous

имхо открытие ФАЙЛА как текстового потока - анархизм

фаил - бинарный поток. А уже декодер над файлов - текстовой

namezys ★★★★
()
Ответ на: комментарий от anonymous

popen предполагает текстовые символы

сфигла ли? Хочешь сказать что unix pipelines тока для текста?

true_admin ★★★★★
() автор топика

> Я сначала всё через subprocess делал, там оно так же падало.

subprocess при чтении из stdout возвращает bytes, и у меня всё работает. А os.popen() в третьем питоне действительно кривой, но он deprecated, и нефиг его использовать.

vasilenko ★★
()
Ответ на: комментарий от vasilenko

А os.popen() в третьем питоне действительно кривой

а я и не его использовал, я использовал subprocess.getstatusoutput(). Ктож знал что оно через os.popen() использует.

true_admin ★★★★★
() автор топика
Ответ на: комментарий от true_admin

Теперь только только костыли.

fd = os.popen('ls')
fd2 = open(fd.fileno(), mode = 'rb', closefd=False)
s = fd2.read()

PS

Тернарный оператор не просто так в 3-м пистоне появился: Гвидо явно на веществах.

anonymous
()
Ответ на: комментарий от anonymous

Тернарный оператор не просто так в 3-м пистоне появился

он ещё в 2.5 был(2006 год). В общем, как только буду свободен я создам баг-репорт, надо это с народом обсудить.

true_admin ★★★★★
() автор топика
Ответ на: комментарий от true_admin

> он ещё в 2.5 был(2006 год)

Крепко же он затянулся, до сих пор не отпустило

надо это с народом обсудить.

Пообсуждайте. Заодно и universal_newlines=False для subprocess.Popen попробуйте. А если кому вдруг понадобится бинарные данные со стандартного ввода читать или в кодировке отличной от системной, то только костыль с fileno

anonymous
()
Ответ на: комментарий от baverman

Ты не поверишь, внутри os.popen вызывается subrpocess.Popen:

proc = subprocess.Popen(cmd,
  shell=True,
  stdout=subprocess.PIPE,
  bufsize=buffering)
return _wrap_close(io.TextIOWrapper(proc.stdout), proc)

Правда, пока это знание мне никак не помогло, locale.setlocale() тоже.

true_admin ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.