Форум сайта python.su
Здравствуйте, уважаемые!
Я уже писал раньше об этой проблеме, но решения так и не было найдено.
Решил повторить, чтобы хотя бы просто порассуждать.
Потому что в инете решения найти я тоже не смог.
Версия Python 3.1, Денвер, винда.
—- Код —
import cgi
form = cgi.FieldStorage()
print(form.read())
—- Код —
—- html-форма —
<form action=“./index.py” method='post' enctype='multipart/form-data'>
free<input type='file' name='free' value='' /><br />
<input type='submit' value='Отправить' />
</form>
—- html-форма —
Вылетает ошибка “UnicodeDecodeError”,
либо передаётся очень крошечная часть файла, как правило не превышающая килобайт.
если запустить такой код
print(sys.stdin.mode)
то выясняется, что входящий поток читается в текстовом режиме mode=“r”.
Поэтому, когда python пытается содержимое потока перевести в юникод, опираясь на кодировку ‘cp1251’
он вываливает ошибку.Я почти уверен, что, если он будет переводить в юникод и на основе utf-8, он также будет падать(пробовал в текстовом режиме прочесть с encoding='utf-8' прочесть тот же файл, та же ошибка).
И отсюда вопрос, как быть?
Причём судя потому, что это проблема возникает в разных версиях и в 3.0 и в 3.0.1, то значит, как это дело работает у разработчиков!?
Пытался найти исходник модуля sys не получилось, видимо он как-то зашит.
Реально из-за этой проблемы на месте топчусь.
Для чистоты эксперимента могу выслать картинку, которую я пытаюсь передать.
Хотя такая байда почти со всеми файлами.
Офлайн
kvazarможет он просто картинку не может отобразить (отпринтить), попробуйте передать маленький текстовый файл с латинскими символами, будет ошибка или нет? а если передавать картинку, дак может её сразу в файл писать.
Офлайн
ошибку даёт не print(), а form.read() следовательно print() можно убрать.
а до записи в файл дело дойти не может, потому что ошибка в form.read(), следовательно не получается даже прочитать stdin.
если бы всё было так просто, я бы сюда не писал -)
Офлайн
К моменту вызова form.read() модуль cgi уже успел распарсить тело post-запроса и загружаемые файлы сохранить в /tmp
Ты бы привел полный текст ошибки
Офлайн
UnicodeDecodeError: ‘charmap’ codec can't decode byte 0x98 in position 1374: character maps to <undefined>
args = ('charmap', b'—————————–808189819792\nCon…e2\x19,4\x9b\x9b\xe1cg*\x8c\x11\x14\x92F\xce\xce', 1374, 1375, ‘character maps to <undefined>’)
encoding = ‘charmap’
end = 1375
object = b'—————————–808189819792\nCon…e2\x19,4\x9b\x9b\xe1cg*\x8c\x11\x14\x92F\xce\xce'
reason = ‘character maps to <undefined>’
start = 1374
with_traceback = <built-in method with_traceback of UnicodeDecodeError object at 0x02D74B70>
——
"а до записи в файл дело дойти не может, потому что ошибка в form.read(), следовательно не получается даже прочитать stdin."
тут да, я был не внимателен, конечно же form.read() читает из временного файла. просто у меня есть ещё своя функция, которая спотыкается при чтении stdin.
а есть ли какой-нибудь вариант заставить временный файл из /tmp не удалять после работы скрипта? хотелось бы посмотреть, что загружается.
Отредактировано (Ноя. 14, 2009 23:08:00)
Офлайн
а вообще вы знаете я был изначально прав! нифига он не “уже успел распарсить тело post-запроса и загружаемые файлы сохранить в /tmp”
отправляю форму, на входе такой код
—-
import cgi
form = cgi.FieldStorage()
—-
—ошибка
–> –>
UnicodeDecodeError Python 3.1.1: Z:\usr\local\python\python.exe
Sun Nov 15 00:13:29 2009
A problem occurred in a Python script. Here is the sequence of function calls leading up to the error, in the order they occurred.
Z:\home\test2.ru\cgi\admin\index.py in ()
87
88 import cgi
=> 89 form = cgi.FieldStorage()
90
91 “”"
form undefined, cgi = <module ‘cgi’ from ‘Z:\usr\local\python\lib\cgi.py’>, cgi.FieldStorage = <class ‘cgi.FieldStorage’>
Z:\usr\local\python\lib\cgi.py in __init__(self=FieldStorage(None, None, ), fp=None, headers={'content-length': ‘1933948’, ‘content-type’: ‘multipart/form-data; boundary=—————————201941623823988’}, outerboundary='', environ=<os._Environ object at 0x01E2BBF0>, keep_blank_values=0, strict_parsing=0)
489 self.read_urlencoded()
490 elif ctype == ‘multipart/’:
=> 491 self.read_multi(environ, keep_blank_values, strict_parsing)
492 else:
493 self.read_single()
self = FieldStorage(None, None, ), self.read_multi = <bound method FieldStorage.read_multi of FieldStorage(None, None, )>, environ = <os._Environ object at 0x01E2BBF0>, keep_blank_values = 0, strict_parsing = 0
Z:\usr\local\python\lib\cgi.py in read_multi(self=FieldStorage(None, None, ), environ=<os._Environ object at 0x01E2BBF0>, keep_blank_values=0, strict_parsing=0)
609 # Create bogus content-type header for proper multipart parsing
610 parser.feed('Content-Type: %s; boundary=%s\r\n\r\n' % (self.type, ib))
=> 611 parser.feed(self.fp.read())
612 full_msg = parser.close()
613 # Get subparts
parser = <email.feedparser.FeedParser object at 0x02F85E10>, parser.feed = <bound method FeedParser.feed of <email.feedparser.FeedParser object at 0x02F85E10>>, self = FieldStorage(None, None, ), self.fp = <_io.TextIOWrapper name='<stdin>' encoding='cp1251'>, self.fp.read = <built-in method read of _io.TextIOWrapper object at 0x01D94730>
Z:\usr\local\python\lib\encodings\cp1251.py in decode(self=<encodings.cp1251.IncrementalDecoder object at 0x02677790>, input=b'—————————–201941623823988\n…xf1-\xc2\xbe\xe7P\xdeh>X9\xf9W8\x03\xeakJX\x85]Y', final=True)
21 class IncrementalDecoder(codecs.IncrementalDecoder):
22 def decode(self, input, final=False):
=> 23 return codecs.charmap_decode(input,self.errors,decoding_table)
24
25 class StreamWriter(Codec,codecs.StreamWriter):
global codecs = <module ‘codecs’ from ‘Z:\usr\local\python\lib\codecs.py’>, codecs.charmap_decode = <built-in function charmap_decode>, input = b'—————————–201941623823988\n…xf1-\xc2\xbe\xe7P\xdeh>X9\xf9W8\x03\xeakJX\x85]Y', self = <encodings.cp1251.IncrementalDecoder object at 0x02677790>, self.errors = ‘strict’, global decoding_table = ‘\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&\’()*+,-./…ПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя'
UnicodeDecodeError: ‘charmap’ codec can't decode byte 0x98 in position 520: character maps to <undefined>
args = ('charmap', b'—————————–201941623823988\n…xf1-\xc2\xbe\xe7P\xdeh>X9\xf9W8\x03\xeakJX\x85]Y', 520, 521, ‘character maps to <undefined>’)
encoding = ‘charmap’
end = 521
object = b'—————————–201941623823988\n…xf1-\xc2\xbe\xe7P\xdeh>X9\xf9W8\x03\xeakJX\x85]Y'
reason = ‘character maps to <undefined>’
start = 520
with_traceback = <built-in method with_traceback of UnicodeDecodeError object at 0x02F77B70>
—ошибка
то есть он не может распарсить тело post-запроса, как и моя функция, потому что stdin открыт в текстовом режиме.
он пытается это тело перевести в юникод и мрёт. конечно. если просто текст послать или текстовый файл проблем нет, а вот картинку не получается никак.
Отредактировано (Ноя. 14, 2009 23:18:48)
Офлайн