title: How to replace `set` using python
body: <p>I'm currently facing a problem where I am giving a thread a reference to a set and I want to be able to replace the set with a mocked database call. I have so far done</p>
  <pre><code>import logging
  import threading
  import time
  from typing import Callable
  
  from loguru import logger
  
  
  class MonitorProduct:
  
      def __init__(self, term: str, is_alive: Callable[[str], bool]) -&gt; None:
          self.is_alive = is_alive
          self.term = term
  
      def do_request(self) -&gt; None:
          time.sleep(.1)
          while True:
              logger.info(f'Checking {self.term}')
              if not self.is_alive(self.term):
                  logger.info(f'Deleting term from monitoring: &quot;{self.term}&quot;')
                  return
  
              time.sleep(5)
  
  
  # mocked database
  def database_terms() -&gt; set[str]:
      return {
          'hello world',
          'python 3',
          'world',
          'wth',
      }
  
  
  def database_terms_2() -&gt; set[str]:
      return {
          'what am I doing wrong',
      }
  
  
  def main() -&gt; None:
      terms: set[str] = set()
  
      while True:
          db_terms = database_terms()
          diff = db_terms - terms
          terms.symmetric_difference_update(db_terms)
  
          for url in diff:
              logger.info(f'Starting URL: {url}')
              threading.Thread(
                  target=MonitorProduct(url, terms.__contains__).do_request
              ).start()
  
          time.sleep(2)
  
          # ----------------------------------------------- #
  
          db_terms = database_terms_2() 
          diff = db_terms - terms
          terms.symmetric_difference_update(db_terms) # &lt;--- terms should only now contain `what am I doing wrong`
  
          # Start the new URLS
          for url in diff:
              logger.info(f'Starting URL 2: {url}')
              threading.Thread(
                  target=MonitorProduct(url, terms.__contains__).do_request
              ).start()
  
          time.sleep(10)
  
  
  if __name__ == '__main__':
      main()
  </code></pre>
  <p>The problem I am now having is that when we do our first db call, it should start threads for each of terms:</p>
  <pre><code>{
    'hello world',
    'python 3',
    'world',
    'wth',
  }
  </code></pre>
  <p>and as you can see we also send in a <code>terms.__contains__</code> for each thread.</p>
  <p>When we do the second call of db - that set should replace the <code>terms</code> to</p>
  <pre><code>{
    'what am I doing wrong',
  }
  </code></pre>
  <p>which should end up exiting the four running threads due to:</p>
  <pre><code>def do_request(self) -&gt; None:
          time.sleep(.1)
          while True:
              logger.info(f'Checking {self.term}')
              if not self.is_alive(self.term):
                  logger.info(f'Deleting term from monitoring: &quot;{self.term}&quot;')
                  return
  
              time.sleep(5)
  </code></pre>
  <p>however the problem is that we cannot replace terms by doing</p>
  <p>terms = ... because we are creating a new set and then bidning that set to the variable terms while the thread still has a reference to the old set.</p>
  <p>My question is, how can I replace the old terms with updating to the newest set without binding a new set?</p>