Что делать , если в Zope проблемы с кодировкой?
Наверно, многие из вас видели это: "UnicodeDecodeError: 'ascii' codec can't decode byte 0xd1 in position 0: ordinal not in range(128)". Почему это происходит? Потому что кто-то в очередной раз программируя str() или unicode() забыл о простой истине: что бы преобразовать одно в другое нужно два параметра: строка и кодировка. Причем кодировка должна соответствовать тому, что есть в строке и должна откуда-то браться.
Несколько раз натыкаясь на эту ошибку мы пытались ее исправить, и ценой неимоверных усилий вытаскивали откуда-то правильную кодировку и исправляли ошибку. Откуда-то - это из запроса Request, из mime_type файла и других не менее трудно доступных мест. Во многих случаях, просто преобразование было не обоснованным и его удаление решало проблему.
Но т.к. программисты Zope по непонятной мне причине любят совать преобразование строки в уникод и обратно куда ни попадя (видимо, забыв что их сервер, по идее идеологов Zope, должен работать в UNICODE), то в конце-концов пришлось порекомендовать некий обходной путь решения таких проблем.
Как вы понимаете, у необязательного параметра "кодировка", в преобразованиях уникода, есть значение по умолчанию. Оно обычно равно ascii, но его можно поменять, отредактировав файл /usr/lib/python2.4/site.py (проконсультируйтесь с вашим местным знатоком по поводу того, где лежит этот файл у вас) и проставив там желаемую кодировку.
Нужное вам место выглядит вот так:
def setencoding(): """Set the string encoding used by the Unicode implementation. The default is 'ascii', but if you're willing to experiment, you can change this.""" encoding = "ascii" # Default value set by _PyUnicode_Init() if 0: # Enable to support locale aware default string encodings. import locale loc = locale.getdefaultlocale() if loc[1]: encoding = loc[1] if 0: # Enable to switch off string to Unicode coercion and implicit # Unicode to string conversion. encoding = "undefined" if encoding != "ascii": # On Non-Unicode builds this will raise an AttributeError... sys.setdefaultencoding(encoding) # Needs Python Unicode build !
Я обычно ставлю 1 в первом операторе if, но у меня настроена локаль :), если у вы не знаете что это такое - то вам лучше удавиться в туалете или сделать явное присваивание, как первый шаг в сторону удавки :).
В любом случае, вы должны понимать - это не решает многочисленных проблем Zope с кодировками и поможет только в одном частном случае: когда кодировка браузера совпадает с кодировкой, в которой работает сервер Zope.
К сожалению, на сегодняшний день я не вижу других вариантов: волна ошибок слишком высока, что бы преодолеть ее одиночными усилиями.
Собственно, выводов для вас два:
- Если вам завтра сдавать ПО заказчику - отредактируйте site.py;
- Никогда без явной небходимости не указывайте преобразование строки в уникод и обратно: критерий явной необходимости простой: вы знаете что указать в качестве кодировки. Во всех остальных случаях нужно разбираться, почему вы в качестве параметра получаете то строку, то уникод и т.п....
Гм... В период разработки и тестирования, лучше site.py не править: хотя бы будете знать где кто закопан...