docs: def read_lock(self):
          """Context manager that grants a read lock.
  
          Will wait until no active or pending writers.
  
          Raises a ``RuntimeError`` if a pending writer tries to acquire
          a read lock.
          """
          me = self._current_thread()
          if me in self._pending_writers:
              raise RuntimeError("Writer %s can not acquire a read lock"
                                 " while waiting for the write lock"
                                 % me)
          with self._cond:
              while True:
                  # No active writer, or we are the writer;
                  # we are good to become a reader.
                  if self._writer is None or self._writer == me:
                      try:
                          self._readers[me] = self._readers[me] + 1
                      except KeyError:
                          self._readers[me] = 1
                      break
                  # An active writer; guess we have to wait.
                  self._cond.wait()
          try:
              yield self
          finally:
              # I am no longer a reader, remove *one* occurrence of myself.
              # If the current thread acquired two read locks, then it will
              # still have to remove that other read lock; this allows for
              # basic reentrancy to be possible.
              with self._cond:
                  try:
                      me_instances = self._readers[me]
                      if me_instances > 1:
                          self._readers[me] = me_instances - 1
                      else:
                          self._readers.pop(me)
                  except KeyError:
                      pass
                  self._cond.notify_all()