Всем известно, что Python - интерпретируемый язык программирования!

Но это не совсем точно, конечно. Чтобы употреблять такие слова нужно говорить о какой-то конкретной имплементации языка.

Всем извстно, что CPython (самая распространенная имплементация) интерпретируемый!

Но это не совсем точно, конечно. Можно сказать, что CPython полукомпилируемый, потому что исходный код компилируется в байткод, который потом исполнется вирутальной машиной (тоже CPython в данном случае). Традиционно же, когда мы говорим о компиляции, то имеем в виду преобразование высокоуровневого языка в конкретный машинный код.

У этой (полу)компиляции в Python есть свои особенности. Исходный код можно скомпилировать в байткод с разными флагами оптимизации: -О, -ОО. В результате у вас появятся *.pyo файлики с байткодом. При этом, в первом случае у вас будут "выключены" assert'ы, а во втором - еще "вырежутся" docstring'и. Оптимизации не особо крутые, чего уж тут говорить, если только в asserta'ах не было какой-то сложной логики.

Как это знание может пригодится? Например, если код разворачивается на CentOS с помощью rpm пакетов, то во время сборки пакета неявно запускается brp-python-bytecompile скрипт, который компилирует Python файлы в *.pyc и *.pyo. Поэтому не стоит потом удивляться, что assert'ы в коде не срабатывают.