I have a small Python program that behaves differently in Python 3.7 and Python 3.8. I'm struggling to understand why. The #threading changelog for Python 3.8 does not explain this.
Here's the code:
import time
from threading import Event, Thread
class StoppableWorker(Thread):
def __init__(self):
super(StoppableWorker, self).__init__()
self.daemon = False
self._stop_event = Event()
def join(self, *args, **kwargs):
self._stop_event.set()
print("join called")
super(StoppableWorker, self).join(*args, **kwargs)
def run(self):
while not self._stop_event.is_set():
time.sleep(1)
print("hi")
if __name__ == "__main__":
t = StoppableWorker()
t.start()
print("main done.")
When I run this in Python 3.7.3 (Debian Buster), I see the following output:
python test.py
main done.
join called
hi
The program exits on its own. I don't know why join() is called.
From the daemon documentation of 3.7:
The entire Python program exits when no alive non-daemon threads are left.
But clearly the thread should be still alive.
When I run this in Python 3.8.6 (Arch), I get the expected behavior. That is, the program keeps running:
python test.py
main done.
hi
hi
hi
hi
...
The daemon documentation for 3.8 states the same as 3.7: The program should not exit unless all non-daemon threads have joined.
Can someone help me understand what's going on, please?