Формальной модели для потоков в Python не существует (эй, в конце концов, не было ни одной для Java в течение многих лет ... надеюсь, одна из них в конечном итоге будет написана для Python).
На практике ни одна реализация Python не выполняет какой-либо дополнительной оптимизации, такой как переупорядочивание операторов или временная обработка общих переменных как локальных потоков, - и вы можете рассчитывать на эти ограничения семантики, даже если они не гарантированы формально.
В частности, CPython, как упоминает @ Rawheiser, использует глобальную блокировку интерпретатора; другие реализации (PyPy, IronPython, Jython, ...) этого не делают (поэтому они могут эффективно использовать несколько ядер с моделью потоков, в то время как CPython требует многопроцессорной обработки для той же цели), поэтому не стоит рассчитывать на это, если вы хотите писать код, который переносим во всех реализациях Python. (Таким образом, вы не должны рассчитывать на «атомарность» операций, которые в CPython являются атомарными только из-за GIL, например, доступ к словарю, - в других реализациях Python несколько потоков могут модифицировать dict одновременно и вызывать ошибки, если вы не защищаете диктовку с помощью замка или тому подобного).