Мне бы очень хотелось, чтобы мое приложение Python работало исключительно со строками Unicode внутри. В последнее время у меня все шло хорошо, но я столкнулся с проблемой обработки путей. POSIX API для файловых систем не является Unicode, поэтому возможно (и на самом деле довольно часто) файлы имеют «недекодируемые» имена: имена файлов, которые не закодированы в заявленной кодировке файловой системы.
В Python это проявляется как смесь объектов unicode и str, возвращаемых из os.listdir().
>>> os.listdir(u'/path/to/foo')
[u'bar', 'b\xe1z']
В этом примере символ '\xe1' закодирован в Latin-1 или чем-то подобном, даже если (гипотетическая) файловая система сообщает sys.getfilesystemencoding() == 'UTF-8' (в UTF-8 этим символом будут два байта '\xc3\xa1'). По этой причине вы получите UnicodeError повсюду, если попытаетесь использовать, например, os.path.join() с путями Unicode, потому что имя файла не может быть декодировано.
Python Unicode HOWTO предлагает следующий совет относительно путей в Unicode:
Обратите внимание, что в большинстве случаев следует использовать API-интерфейсы Unicode. Bytes API следует использовать только в системах, где могут присутствовать недекодируемые имена файлов, то есть в системах Unix.
Поскольку меня в основном интересуют системы Unix, означает ли это, что я должен перестроить свою программу, чтобы иметь дело только со строками байтов для путей? (Если да, то как я могу поддерживать совместимость с Windows?) Или есть другие, лучшие способы борьбы с недекодируемыми именами файлов? Являются ли они настолько редкими «в дикой природе», что я должен просто попросить пользователей переименовать их чертовы файлы?
(Если лучше просто иметь дело со строками байтов внутри, у меня есть дополнительный вопрос: как хранить строки байтов в SQLite для одного столбца, сохраняя при этом остальные данные в виде понятных строк Unicode?)