title: Does python threading.Lock() lock everything that needs locking?
body: <p>Script below is abstracted. My question is about the use of <code>threading.Lock()</code></p>
  
  <p>Locking limits access to "shared resources" but I am nervous about how far that goes. I have <em>objects attributes that are lists of objects which have attributes that are arrays</em> in this example. In some cases the dependency will go farther.</p>
  
  <p>Does <code>Lock()</code> "know" for sure about everything that needs to be locked?</p>
  
  <p>The output of the script below is also shown. The purpose of the script is mostly for discussion - It doesn't fail, but I am not confident that it is Locking everything it needs to.</p>
  
  <pre><code>start:   [array([0, 1]), array([0, 1, 2]), array([0, 1, 2, 3])]
  append an object
  done!
  finish:  [array([505, 605]), array([10, 11, 12]), array([10, 11, 12, 13]), array([5])]
  
  
  import time
  from threading import Thread, Lock
  import numpy as np
  
  class Bucket(object):
      def __init__(self, objects):
          self.objects = objects
  
  class Object(object):
      def __init__(self, array):
          self.array = array
  
  class A(Thread):
      def __init__(self, bucket):
          Thread.__init__(self)
          self.bucket      = bucket
      def run(self):
          nloop            = 0
          locker           = Lock()
          n = 0
          while n &lt; 10:
              with locker:  
                  objects = self.bucket.objects[:]  # makes a local copy of list each time
              for i, obj in enumerate(objects):
                  with locker:
                      obj.array += 1
                  time.sleep(0.2)
              n += 1
              print 'n: ', n
          print "done!"
          return
  
  objects = []
  for i in range(3):
      ob = Object(np.arange(i+2))
      objects.append(ob)
  bucket = Bucket(objects)
  
  locker           = Lock()
  
  a = A(bucket)
  print [o.array for o in bucket.objects]
  
  a.start()
  
  time.sleep(3)
  
  with locker:
      bucket.objects.append(Object(np.arange(1)))  # abuse the bucket!
      print 'append an object'
  time.sleep(5)
  
  print [o.array for o in bucket.objects]
  </code></pre>