Seriously, threads are evil.
Threads in Python still have all the pitfalls and complications they have in other languages, it's just that they cannot use multiple cores or hardware threads. So you get all the evil bits (race conditions, deadlocks, having to protect access to shared state, etc), but you miss out on all the performance benefits threads can have on parallel hardware.
In Python, threads are only useful as an abstraction of things that have to run concurrently, even though they never do.
> have to run concurrently, even though they never do.
is way off base.
Likewise, if you're doing CPU-heavy crunching (likely implemented in C or Cython), you can release the GIL and let the interpreter run some other bytecode at the same time.
This is just false. Threads still offer performance benefits for non-CPU bound operations. For example, if you are trying to download data from 100 different sources, you could do it in a single thread, but python would spend most of its time idling while other prosseses do work, or you could have 100 threads, so python can do work while it is waiting on other stuff to get done.