Thread locals are an interesting idea: a way to give each thread its own
storage, useful for state that you don't want to share between threads.

Let's look at the Python official docs about
threading.local.
Here is all of it:

class threading.local

A class that represents thread-local data. Thread-local data are data
whose values are thread specific.
To manage thread-local data, just create an instance of local (or a subclass) and store attributes on it:

mydata = threading.local()

mydata.x = 1

The instance’s values will be different for separate threads.

For more details and extensive examples, see the documentation string of the _threading_local module.

Um. Wat. So mydata.x exists if it's assigned an immutable value, and does
not exist if it's assigned a mutable value?

I don't fully understand this.

It's a bit irksome that this is glossed over in the published python docs and
lies here waiting to bite unsuspecting users.
Remind me to submit a docs patch...

Mutable threadlocals part 2: Subclass threading.local

But here's a better way, based on a close read of the docstring that was
mentioned in the docs.
It works if you subclass threading.local and create your mutable
object inside __init__.

You can see what happens if you do that by reading the _threading_local
source: both __new__ and __getattribute__ are defined such that your
__init__() gets run for each thread as needed, with locking around it.