code: def put(self, item, block=True, timeout=None):
          
          if self.full():
              if not block:
                  raise Full()
  
              current = compat.getcurrent()
  
              waketime = None if timeout is None else time.time() + timeout
              if timeout is not None:
                  scheduler.schedule_at(waketime, current)
              self._waiters.append((current, waketime))
  
              scheduler.state.mainloop.switch()
  
              if timeout is not None:
                  if not scheduler._remove_timer(waketime, current):
                      self._waiters.remove((current, waketime))
                      raise Full()
  
          if self._waiters and not self.full():
              scheduler.schedule(self._waiters.popleft()[0])
  
          if not self._open_tasks:
              self._jobs_done.clear()
          self._open_tasks += 1
  
          self._put(item)
docs: put an item into the queue
  
          .. note::
  
              if the queue was created with a `maxsize` and it is currently
              :meth:`full`, this method will block the calling coroutine until
              another coroutine :meth:`get`\ s an item.
  
          :param item: the object to put into the queue, can be any type
          :param block:
              whether to block if the queue is already :meth:`full` (default
              ``True``)
          :type block: bool
          :param timeout:
              the maximum time in seconds to block waiting. with the default of
              ``None``, it can wait indefinitely. this is unused if `block` is
              ``False``.
          :type timeout: int, float or None
  
          :raises:
              :class:`Full` if the queue is :meth:`full` and `block` is
              ``False``, or if `timeout` expires.