Я считаю, что проблема в том, что codecs.BOM_UTF8
- это строка байтов, а не строка Юникода. Я подозреваю, что обработчик файлов пытается угадать, что вы на самом деле имеете в виду, основываясь на «Я должен писать Unicode как текст в кодировке UTF-8, но вы дали мне строку байтов!»
Попробуйте написать строку Unicode для метки порядка байтов (т.е. Unicode U + FEFF) напрямую, чтобы файл просто кодировал это как UTF-8:
import codecs
file = codecs.open("lol", "w", "utf-8")
file.write(u'\ufeff')
file.close()
(Это, кажется, дает правильный ответ - файл с байтами EF BB BF.)
EDIT: предложение S. Lott об использовании "utf-8-sig" в качестве кодировки лучше, чем явное написание самой спецификации, но я оставлю здесь этот ответ, поскольку он объясняет раньше шел не так.