title: How to use a thread in a context manager?
body: <p>Consider this <code>threading.Thread</code> class:</p>
  
  <pre><code>class Sleeper(threading.Thread):
      def __init__(self, sleep=5.0):
          threading.Thread.__init__(self)
          self.event = threading.Event()
          self.sleep = sleep
  
      def run(self):
          while self.sleep &gt; 0 and not self.event.is_set():
              self.event.wait(1.0)
              self.sleep -= 1
  
      def stop(self):
          self.event.set()
  </code></pre>
  
  <p>It sleeps for a certain amount of time and exits or is stopped before reaching that amount.</p>
  
  <p>I use it as:</p>
  
  <pre><code>sleeper = Sleeper()
  try:
      sleeper.start()
      # do stuffs here
  except:
      # handle possible exceptions here
  finally:
      sleeper.stop()
  </code></pre>
  
  <p>And I would much rather use it like a context manager:</p>
  
  <pre><code>with Sleeper():
      # do stuffs here
  </code></pre>
  
  <p>and then the thread is stopped when exiting the <code>with</code> block.</p>
  
  <p>I have tried adding <code>__enter__</code> and <code>__exit__</code> methods and it seems to work but I'm not sure this is the way to go:</p>
  
  <pre><code>def __enter__(self):
      self.start()
      return self
  </code></pre>
  
  <p>and </p>
  
  <pre><code>def __exit__(self, type, value, traceback):
      self.stop()
  </code></pre>
  
  <p>But I'm really not sure what I'm doing here. How should it be done properly?</p>