Старый PC на работе ушёл в синий экран и после этого компиляция через Emscripten не работала, выдавало странную ошибку, про которую ничего не было в интернете. Полный rebuild ничего не давал, всё то же. Закрыл глаза, включил режим детектива. Вылетело в синий экран, наверное, потому что компьютер ушёл в своп. Жёсткий диск немного поврёжден, и, наверное, при чтении обратно исказились заголовки страниц виртуальной памяти, используемых виндовсом, поэтому он запаниковал, т.к. был доступ к повреждённой памяти из-под ядра. В это время компилялся Emscripten и я краем глаза видел, что он в процессе вызывает скрипты на питоне. Питон, как известно, компилирует *.py в байткод с расширением *.pyc и кеширует их: если вызвать *.py, то он проверит, есть ли рядом *.pyc, и тогда выполняет его. Видимо, на момент синего экрана питон, как часть toolchain'а CMake для Emscripten, занимался именно этим: писал в *.pyc, но тут - синий экран, и файл не до конца записан. Когда в следующий раз я пытаюсь перекомпилять, он запускает повреждённый *.pyc и жалуется.
Решение было простое - переустановить Emscripten SDK, тогда все скрипты Python будут ванильными без сопутствующих *.pyc. Попробовал - так и случилось, всё снова стало работать.
Это, конечно, нехорошо, что винт повреждён, но и Python ведёт себя как дурак. По сути, *.pyc это implementation detail, по сути кэш, сделанный для удобства. Наличие или отсутствие кэша не должно никак влиять на поведение. Если Python видит, что *.pyc повреждён, почему он не пытается обнулить кэш и перестроить заново, а вместо этого ругается непонятно о чём? Я недоволен и разозлён, что такая хрень до сих пор происходит в 2017.