- Don't check. Programs will crash if a thread-local variable is passed outside the thread (C, C++)
- Naive interpreter. Everything works, slowly, because the worst case code is used for everything. (CPython)
- Really clever just-in-time recompilation when what seemed to be thread-local suddenly gets accessed from another thread. (PyPy, Java?)
- Compile time checking to prevent this. (Rust)
- No threads (classic Javascript)
- Explicit shared areas into which only certain types can be placed (ECMAscript 2018)
1. Python doesn't have thread-local variables 2. Python's memory model around threading is what prevents any optimization.
Both are clearly incorrect. For example, take Java. You have the same behaviour as Python: your VM won't crash & your code won't even generate a panic. Java clearly has thread-local variables & an optimizing compiler.
Python's inhibition around optimizing is partially around the guarantees they make around APIs that do self introspection but mainly around keeping the interpreter simple. For a counterpoint see PyPy, Cython, JPython, IronPython etc which optimize Python just fine. They mostly trip over module extensions being tied directly to the non-standardized CPython module API & that API is tied intimately to implementation decisions of CPython.